C++ 迭代或使用计数器,这就是问题所在

C++ 迭代或使用计数器,这就是问题所在,c++,stl,coding-style,C++,Stl,Coding Style,每当有人开始使用STL并且他们有一个向量时,您通常会看到: vector<int> vec ; //... code ... for( vector<int>::iterator iter = vec.begin() ; iter != vec.end() ; ++iter ) { // do stuff } 向量向量机; //... 代码。。。 for(vector::iterator iter=vec.begin(); iter!=vec.

每当有人开始使用STL并且他们有一个向量时,您通常会看到:

vector<int> vec ; //... code ... for( vector<int>::iterator iter = vec.begin() ; iter != vec.end() ; ++iter ) { // do stuff } 向量向量机; //... 代码。。。 for(vector::iterator iter=vec.begin(); iter!=vec.end(); ++国际热核聚变实验堆(iter) { //做事 } 我只是觉得整个
vector::iterator
语法令人恶心。我知道您可以
typedef vector::iterator veciterprint
,这稍微好一点

但问题是,好的ol有什么错

for( int i = 0 ; i < vec.size() ; i++ ) { // code } 对于(int i=0;i当谈到std::vector时,我认为在循环中使用下标操作符是很好的,在性能方面可能差不多。使用迭代器的优势在于,当您希望将向量与其他
std
函数(如中)一起使用时。

我通常对向量使用for循环-对我来说,这是处理此类事情的规范方法。不要让任何人告诉你迭代器更快-请参阅

另外,迭代器和构造(如foreach)的极端支持者倾向于忽略的一件事是,对于for循环,实际上有一个整数索引,除了访问集合元素之外,还可以执行其他操作,这在各种情况下都非常有用


但是,如果我要使用STL算法,或者迭代其他容器类型,比如std::map,我当然会使用迭代器。

一般来说,迭代器不局限于std::vector,因为迭代器可以访问集合的内部并知道迭代的状态,所以迭代器比索引更有效


在std::vector的情况下,循环中的迭代器在进行优化编译时将简化为指针算法。一个聪明的编译器也许可以对计数器循环执行同样的操作,并且性能上应该没有任何差异,但是一般来说(对于更复杂的集合),您应该假设迭代器将为您提供最快的代码。

使用C++0x,您不会遇到这种困境。您将使用新的:)

我建议使用迭代器,因为它们更通用。如果在开发周期的后期,您决定使用std::list比使用std::vector更好(也许您会发现性能有问题,因为您需要从容器的头部弹出元素),更改迭代器版本需要更少的努力。

我认为我的论点不是很有力,但我几乎总是使用迭代器版本

typedef std::vector<int> MyIndexes; // or whatever
MyIndexes indexes;
for (Something::iterator iter = indexes.begin(); iter != indexes.end(); ++iter);
typedef std::vector myindex;//或者别的什么
我的指数;
for(Something::iterator iter=index.begin();iter!=index.end();++iter);

现在,如果我必须将向量更改为list或类似的东西,我只需要更改typedef。这在一些场合是有用的。auto关键字将使这一点更好,但我不能等待C++0x for loop:)

如果您在一个范围内创建、使用和销毁一个向量,那么使用迭代器抽象并没有多大好处,但是对于更丰富的容器,例如,
std::map
,开销是值得的

迭代器非常适合于泛型编程。没有任何机械和簿记会模糊代码的意图,您可以获得极大的灵活性。想把一个向量复制到另一个吗

std::vector<int> v1, v2;
// ...

std::copy(v1.begin(), v1.end(), v2.begin());

迭代器允许单个模板处理各种情况。

当您使用索引执行对容器(
std::vector
或任何其他内容)的基本顺序访问时,您将随机访问要求强加给底层数据结构,而实际上您的算法中不需要这种访问。随机访问需求是一个非常强的需求,而顺序访问的需求要弱得多。在没有充分理由的情况下强加更强的要求是一个重大的设计错误

因此,对您的问题的正确答案是:尽可能使用顺序(迭代器)访问,只有在绝对必要时才使用随机(索引)访问。尽可能避免索引访问

如果您的算法严重依赖于容器是随机可访问的,那么它将成为算法的外部需求。在这种情况下,您可以毫无保留地使用索引访问。但是,如果可以只使用迭代器实现相同的算法,那么最好只使用迭代器,即完全依赖顺序访问


当然,上述规则虽然正确,但只有在某种程度上是通用的代码中才有意义。如果代码的某些其他部分非常具体,您可以确定正在使用的数据结构是
std::vector
,并且始终是
std::vector
,则访问方法不再重要。你喜欢什么就用什么。但是,在顺序访问完全足够的情况下,我仍然会避免索引访问。

个人而言,我更喜欢使用迭代器进行迭代。与通过索引、IMHO进行访问相比,显示的意图更好,而且对于不同的容器,编码习惯用法是相同的。

对此总是三思而后行。对于计算机来说,这无关紧要,编译器足够大,可以自行处理,并且最终会为任何一种情况生成同样好的代码

但是程序员呢


看到(
for(int i=0;i标记的答案是错误的。根本没有“访问”正在进行的是此代码

在这种情况下,真正的答案应该是没有区别的,除非向量实现非常不合适,除非使用迭代器会稍微慢一点


对于存储在数组中的内容,迭代器是一个相当愚蠢的概念。之所以这样做,是因为其他一些情况不能直接作为数组来访问,所以更一般地说,它们鼓励迭代器用于所有事情。尽管迭代器非常麻烦,而且只在少数特殊情况下使用才有意义。

IMO,usi任何一个都没有抓住重点
std::ostream_iterator<int> output(std::cout, " ");
std::copy(v1.begin(), v2.end(), output);
typedef std::vector<int> MyIndexes; 
MyIndexes indexes;
for (Something::iterator iter = indexes.begin(); iter != indexes.end(); ++iter);
template <class iter>
void my_algorithm(iter a, iter b) { 
    for (iter i=a; i!=b; ++i) 
        do_stuff(*i); 
}