Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ i=v.end()是否可以在for循环外进行优化?_C++_C++11 - Fatal编程技术网

C++ i=v.end()是否可以在for循环外进行优化?

C++ i=v.end()是否可以在for循环外进行优化?,c++,c++11,C++,C++11,我刚才看到这样的情况: vector<int> x { 1, 2, 3, 4 }; for (auto i = x.begin(); i != x.end(); ++i) { // do stuff } 向量x{1,2,3,4}; 对于(自动i=x.begin();i!=x.end();++i) { //做事 } 这样做是否更好: vector<int> x { 1, 2, 3, 4 }; for (auto i = x.begin(), end = x.end(

我刚才看到这样的情况:

vector<int> x { 1, 2, 3, 4 };
for (auto i = x.begin(); i != x.end(); ++i)
{
  // do stuff
}
向量x{1,2,3,4};
对于(自动i=x.begin();i!=x.end();++i)
{
//做事
}
这样做是否更好:

vector<int> x { 1, 2, 3, 4 };
for (auto i = x.begin(), end = x.end(); i != end; ++i)
{
  // do stuff
}
向量x{1,2,3,4};
对于(自动i=x.begin(),end=x.end();i!=end;++i)
{
//做事
}

我想我认为优化器会处理这个问题。我错了吗?

最有可能的是优化器会为您完成这项工作

顺便问一句,为什么
decltype(x.begin())
为您提供了
auto

for (auto i = x.begin(); i != x.end(); ++i)
{
  // do stuff
}
甚至:

for (auto i : x)
{
  // do stuff
}

后者是
范围。

您不应该这样做。因为某些操作(如
erase
)可能会使迭代器无效


如果您确定
for
循环中没有此类操作,请随意操作。但通常编译器会为您进行优化。(如果打开优化标志)

是的,第二个版本可能会更优化,只要您的容器从未被修改,但编译器无法判断容器从未被修改

通过检查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
    }
  }
}
任何以
开头的变量仅用于说明目的,且
使用std::begin;使用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);
  }
}
它不允许您中断或返回到外部范围,但它非常接近基于C++11的范围


如果你缺少基于远程的for和lambdas,你可能是一个完全疯狂的人,并将上面的大部分实现为一个宏。。。std::begin
是否使用具有完美前移的帮助函数来避免污染函数体,mayhap.

是的,每次都会对表达式求值,但编译器通常会对其进行优化。如果关闭编译器优化,最好使用后一个比较程序集并查看。(另外,如果循环体可能从
x
擦除
,则第二个版本是错误的,因为时间太晚了,而且我没有想清楚。)p@texasbruce“如果你关闭编译器优化,最好使用后一个”-如果你关闭优化,你显然不关心性能,无论如何。因为时间太晚了,我没有想清楚P:D至于第二个,MSVS2010不支持这种语法。嗯,当我使用
erase
来阻止这种情况发生时,我通常会后退。
foreach( vec_expression, [&]( int x ) {
} );