BOOST_FOREACH迭代rvalue容器有非const ref值的错误

时间:2014-03-06 08:24:48

标签: c++ boost

我正在使用g ++ 4.4.7 20120313

class obj { int a; }

std::list<obj> list;

BOOST_FOREACH(obj& v, list) { } // ok    
BOOST_FOREACH(const obj& v, list) { } // ok    

std::list<obj> getlist() { ... }

BOOST_FOREACH(obj& v, getlist()) { } // error: invalid initialization of reference of type 'obj&' from expression of type 'const obj'
BOOST_FOREACH(const obj& v, getlist()) {} // ok

为什么会出错? 我为什么要使用const obj&amp;而不是obj&amp; ?

3 个答案:

答案 0 :(得分:3)

getlist()返回一个临时对象。通常,临时消失(它的生命周期结束)在它出现的表达式的末尾消失。临时值可以作为标准中的特殊情况绑定到const引用,但不能绑定到非const引用。

要回答原因,请考虑将临时引用绑定到非const引用的含义:当临时生命周期结束时,通过引用所做的任何更改都将丢失。通过禁止这一点,C ++在这里保护你。

Sutter在one of his older GOTWs中介绍了这一点。

答案 1 :(得分:2)

BOOST_FOREACH(obj& v, getlist()) { }

您是否尝试过右值参考?

BOOST_FOREACH(obj&& v, getlist()) { }

我建议更新到至少g ++ 4.6,然后你可以在C ++ 11中使用新的基于范围的for循环:

for (obj&& v : getlist()) { }

答案 2 :(得分:1)

我们可以简化以下内容:

int f() { return 99 ; }
int main() {
    const int& p = f() ; // OK
    int& p = f() ;       // error: invalid initialization of non-const reference
                         // of type ‘int&’ from an rvalue of type ‘int’
    return 0 ;
}

这对你更有意义吗?