迭代矢量/映射数据结构C ++

时间:2011-02-15 16:05:21

标签: c++ vector map

这些天我一直在广泛地使用地图/矢量,但是在迭代它们时有疑问

哪一个更好?

for(vector<string>::iterator it=myvec.begin(); it!=myvec.end(); ++it){
}

for(int i=0; i < myvec.size(); i++){ 
       myvec[i]
}

首先,他们是否打算做同样的事情?

5 个答案:

答案 0 :(得分:1)

当您使用手动循环时,它没有太大区别。但是当你使用STL函数(比如来自<algorithm>的函数)时,你没有选择。您必须使用迭代器,因为STL函数与迭代器一起使用,而不是使用索引。

例如,如果您想使用vector<int>计算std::accumulate中所有整数的总和,那么您必须这样做:

 int sum = std::accumulate(vints.begin(),vints.end(),0);

所以我的建议是:养成使用迭代器的习惯,因为它给你一致性,也逐渐让你对迭代器的理念感到满意。它给人一种通用感!

答案 1 :(得分:1)

两者都可以同样好地迭代向量。我喜欢迭代器,因为我已经看到索引做了不好的事情 - 主要是有人使用一个容器的索引到达不同的容器。如果第二个容器较小,则无效。

如果您只想为每个元素执行某些操作,可以使用BOOST_FOREACH

std::list<int> list_int( /*...*/ );
BOOST_FOREACH( int i, list_int )
{
    // do something with i
}

答案 2 :(得分:0)

这取决于在执行循环体时是否需要知道元素在其容器中的位置。如果这样做,则需要使用第二种形式。如果没有,请使用第一个,因为它更通用,因此更灵活;您可以将myvec的类型更改为支持迭代器的任何内容,即使它不支持随机访问。

答案 3 :(得分:0)

来自Meyers“Effective STL”,第43项。

“首选算法调用手写循环”

  • 算法通常比循环程序员生成
  • 更有效
  • 写循环更容易出错
  • 算法代码更易于阅读

尽可能经常使用带迭代器的算法。

std::for_each(myvec.begin(), myvec.end(), [](const string& s) {
   /* your code here */
});

答案 4 :(得分:0)

我尝试尽可能地隐藏容器的底层实现。

因此,在您的示例中,我将首先使用typedef而不是直接引用向量(稍后您将看到原因):

typedef std::vector<string> MyStringCollection;

然后,我尝试使用尽可能少依赖底层实现的构造。在这种情况下,我想迭代容器并使用容器中的值,如下所示:

for(MyStringCollection::iterator it=mycollection.begin(); it!=mycollection.end(); ++it)
   {
   // use *it
   } 

使用typedef,您的集合的用户只需使用MyStringCollection::iterator,而无需知道MyStringCollection实际上是什么。

请注意,在C ++ 0x中,您可以使用auto,这甚至更短(使得我对typedef的参数不太相关)。

这样做的好处是,现在可以很容易地将MyStringCollection从std :: vector更改为std :: list。如果由于性能原因您决定列表更适合,您只需要:

  • 将typedef从std :: vector更改为std :: list
  • 快速查看使用MyStringCollection的所有地方(比查找std :: vector的所有用法更容易找到