C++ C++;11 for循环是否允许新的或更好的优化?

C++ C++;11 for循环是否允许新的或更好的优化?,c++,optimization,for-loop,c++11,C++,Optimization,For Loop,C++11,在C++11中,我们现在可以执行以下操作: void dosomething( std::vector<Thing>& things ) { for( Thing& thing : things ) { dofoo( thing ); wiizzz( thing ); tadaa( thing ); } } void dosomething(std::vector&things) { for(

在C++11中,我们现在可以执行以下操作:

void dosomething( std::vector<Thing>& things )
{
    for( Thing& thing : things )
    {
        dofoo( thing );
        wiizzz( thing );
        tadaa( thing );
    }

}
void dosomething(std::vector&things)
{
for(事物&事物:事物)
{
多福(东西);
wiizzz(东西);
塔达(事物);
}
}
我知道lambda的添加和使用是语法上的糖分,但它提供了有趣的优化机会


for循环呢?这仅仅是语法上的甜点,还是编译器可以优化某些情况,而这些情况对于手写循环来说是无法做到的,或者是太难做到的

这只是一个语法上的甜点,因为标准说它相当于带迭代器的循环[编辑:这意味着与循环结束编辑的等价物相比,它不向编译器提供任何附加信息]。但您可能会获得更好的性能,因为它相当于:

for(auto iter = con.begin(), end = con.end(); iter != end; ++iter)
{
    auto& ref = *iter;
    // ...
}
虽然大多数人可能会写:

for(auto iter = con.begin(); iter != con.end(); iter++)
{
    // use *iter directly
    // ...
}
如果con.end()、iter++或*iter不是微不足道的,那么这可能会更慢

[编辑:

lambda是语法上的糖


不完全是。与for循环不同,它允许编译器直接捕获堆栈帧基指针,对于通过引用捕获的变量,与手工制作的函数对象相比,每次使用它都会间接保存一个地址。-end edit]

可能,但可能不是。它确实消除了创建不使用的索引/计数器变量的可能性。正常的for循环也不需要这样做,但这种情况更可能发生,因为有些人已经习惯了这样做


事实上,即使这样也不太可能有什么不同。一、 至少,很难想象一个如此复杂的编译器团队,他们甚至对支持C++0x有丝毫的渴望,他们还没有处理过检测和消除创建和递增一个从未使用过的循环索引这一相对琐碎的问题。

确实
for(Thing&Thing:things)
在c++0x中指定顺序?或者,
thing
可以以任何顺序出现吗?它只是从给定容器的begin()成员(如果它是一个类)获取迭代器,然后迭代直到到达end()迭代器。因此,它依赖于迭代器,如果需要,也依赖于容器。如果是原始数组(或者也是数组语义类?),它将从[0]开始,并在到达[size]时结束。是否确实缓存了
end()
?这意味着您不能对语义不同的集合进行变异(对于插入/删除时不会使迭代器无效的集合,例如,
list
)。我猜它假定容器不会更改。如果会的话,使用stl算法可能是一种更好的方法。@Motti:标准明确地说,它等同于上述代码(嗯,更复杂一点,因为它的措辞是以范围为单位的)。无论如何,如果容器没有使迭代器无效,则end()不是invalidates。那有什么问题?只要不破坏此代码,您就可以更改容器。虽然我看不到任何立即的优化机会,但编译器可以根据“仿佛”规则执行任何它想执行的操作。@sellibitze:这确实使编译器更容易证明
end
不会更改,因此可以缓存而不是重新计算。如果你的循环很复杂,这可能是一个优化,否则就会错过。