这些天我一直在广泛地使用地图/矢量,但是在迭代它们时有疑问
哪一个更好?
for(vector<string>::iterator it=myvec.begin(); it!=myvec.end(); ++it){
}
或
for(int i=0; i < myvec.size(); i++){
myvec[i]
}
首先,他们是否打算做同样的事情?
答案 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。如果由于性能原因您决定列表更适合,您只需要: