这两种迭代容器的方法的优点/缺点是什么/您更喜欢哪一种以及为什么:
for (MyClass::iterator i = m.begin(), e = m.end() ; i != e ; i++)
{
// ...
}
或者
for (MyClass::iterator i = m.begin() ; i != m.end() ; i++)
{
// ...
}
附属问题:i++ 还是 ++i?为什么?
这两种迭代容器的方法的优点/缺点是什么/您更喜欢哪一种以及为什么:
for (MyClass::iterator i = m.begin(), e = m.end() ; i != e ; i++)
{
// ...
}
或者
for (MyClass::iterator i = m.begin() ; i != m.end() ; i++)
{
// ...
}
附属问题:i++ 还是 ++i?为什么?
If the iterator is non-trivial (ie. not a pointer), ++i is definitely faster as it doesn't involves a copy to a temporary, which may or may not be optimized out.
The first form is a little faster but could be wrong if you erase or insert things in the loop.
For simple iteration over a container I use
#define foreach BOOST_FOREACH // in some header
foreach(MyType &element, any_container) {
// deal with element
}
most of the time for succinctness and clarity.
除非您关闭了优化,否则两者都是等效的。至于 i++ 或 ++i,++i 效率更高,因为它不涉及临时值。
对于普通的 stl 迭代器,没有太大的区别,但是如果你的集合很复杂并且要求 end 很昂贵,那么只要求 end 一次可能会更快。
同样,对于 ++i 与 i++,当迭代器是一个复杂的类(而不仅仅是 stl 迭代器中的指针)时,++i 可能是一个更昂贵的操作,而 i++ 发生的是它正在递增迭代器但返回一个副本迭代器处于其先前状态。对于 ++i 它以当前状态返回迭代器,因此可以只返回对自身的引用。
通常最好只在探查器发现存在问题时才优化代码——最好让代码尽可能易于阅读。
实际上,我总是做第二个,尽管有时我确实担心多次调用 end 会减慢速度。我的印象是这会被优化,但不确定。
并且 ++i 绝对是。它永远不会比 i++ 慢,如果有的话,它会更快。
第一个更快,因为end()
不是每次迭代都调用。不,优化器不能轻易地为你缓存它,因为它不知道容器的大小在这次迭代中是否发生了变化(因此最终移动了)。由于别名问题,这也适用于 const 容器。
i++
返回 i 的副本,然后递增。++i
递增,然后返回递增的值。因此,当您丢弃返回值时,请使用它,++i
因为它需要做的工作更少(不复制)。优化器很可能会修复内联i++
调用,因此它的速度与它一样快,++i
但不要依赖它。
我?我用
for(int i = 0; i < m.size(); i++) {
// ... do something with m[i]
}
因为它是最短最清晰的。为什么int
而不是MyClass::size_type
?因为它更简单,到目前为止我从来不用担心边缘情况。为什么i++
?因为对于基本类型,它总是被优化为++i
,并且它对同事来说不那么混乱。作为奖励,我也可以将i
其用作数值。使用迭代器,我必须保留一个单独的计数器,或者使用std::distance
.
obecalp指出,这不适用于一半的标准容器,例如list
and map
。事实上,那些需要使用适当的迭代器。iterator
相关地,在编写通用代码时,您应该始终使用 an 。
The C++ "for every element in container" loop is the most efficient where the context doesn't call for iterative logic.
for(Item& i : Container)
{
dosomething(i);
}
or
for(const Item& i : Container)
{
dosomething(i);
}
Boost.Foreach introduces a nice way:
#define foreach BOOST_FOREACH
// ...
Container<Item> container;
// ...
foreach (Item item, container) {
// do some stuff with the item
}