我刚刚看到这样的事情:
vector<int> x { 1, 2, 3, 4 };
for (auto i = x.begin(); i != x.end(); ++i)
{
// do stuff
}
这样做更好:
vector<int> x { 1, 2, 3, 4 };
for (auto i = x.begin(), end = x.end(); i != end; ++i)
{
// do stuff
}
我想我认为优化器会处理这个问题。我错了吗?
答案 0 :(得分:7)
是的,第二个版本可以更优化,只要您的容器永远不会被修改但是,编译器无法告诉容器永远不会被修改。
通过检查基于C ++ 11范围的for
循环,可以找到“最优”的循环结构。
代码:
for( auto x : vec_expression ) {
// body
}
大致翻译成:
{
auto&& __container = vec_expression;
using std::begin; using std::end;
auto&& __end = end(container)
for( auto __it = begin(container); __it != __end; ++__it ) {
auto x = *__it;
{
// body
}
}
}
其中以__
开头的任何变量仅用于展示目的,using std::begin; using std::end;
在// body
内被神奇地删除。 (请记住,任何包含__
的变量都保留给编译器实现。)
如果您的编译器中有lambda支持,则可以编写自己的版本:
template<typename Container, typename Lambda>
void foreach( Container&& c, Lambda&& f ) {
using std::begin; using std::end;
auto&& e = end(c);
for( auto it = begin(c); it != e; ++it ) {
f(*it);
}
}
使用如下:
foreach( vec_expression, [&]( int x ) {
} );
它不会让你破坏或返回到外部范围,但它非常接近C ++ 11基于范围的。
如果你缺少基于范围的for和lambdas,你可能是一个完全疯了的人并且将上面的大部分内容实现为一个宏... std::begin
使用辅助函数完成fowarding以避免污染功能的主体,mayhap。
答案 1 :(得分:5)
最有可能的是优化器会为你完成这项工作。
顺便说一下,为什么decltype(x.begin())
为什么auto
?
for (auto i = x.begin(); i != x.end(); ++i)
{
// do stuff
}
甚至:
for (auto i : x)
{
// do stuff
}
后者是range for
:http://en.cppreference.com/w/cpp/language/range-for。
答案 2 :(得分:1)
你不应该。因为像erase
这样的操作可能会使迭代器失效。
如果您确定for
循环内没有此类操作,请随意执行此操作。但通常编译器会为您进行优化。 (如果你打开优化标志)