在C ++ 0x lambda中通过复制捕获引用变量

时间:2011-06-30 01:50:46

标签: c++ gcc lambda c++11 g++

根据this question的答案和注释,当通过值捕获引用变量时,lambda对象应该复制引用的对象,而不是引用本身。但是,海湾合作委员会似乎没有这样做。

使用以下测试:

#include <stddef.h>
#include <iostream>

using std::cout;
using std::endl;

int main(int argc, char** argv)
{
    int i = 10;
    int& ir = i;

    [=]
    {
        cout << "value capture" << endl
             << "i: " << i << endl
             << "ir: " << ir << endl
             << "&i: " << &i << endl
             << "&ir: " << &ir << endl
             << endl;
    }();

    [&]
    {
        cout << "reference capture" << endl
             << "i: " << i << endl
             << "ir: " << ir << endl
             << "&i: " << &i << endl
             << "&ir: " << &ir << endl
             << endl;
    }();    

    return EXIT_SUCCESS;
}

使用-std=c++0x使用GCC 4.5.1进行编译,并运行以下输出:

value capture
i: 10
ir: -226727748
&i: 0x7ffff27c68a0
&ir: 0x7ffff27c68a4

reference capture
i: 10
ir: 10
&i: 0x7ffff27c68bc
&ir: 0x7ffff27c68bc

通过复制捕获时,ir仅引用垃圾数据。但是,当通过引用捕获时,它正确引用了i

这是GCC中的错误吗?如果是这样,有人知道后来的版本是否修复了它?什么是正确的行为?

修改

如果第一个lambda函数更改为

[i, ir]
{
    cout << "explicit value capture" << endl
         << "i: " << i << endl
         << "ir: " << ir << endl
         << "&i: " << &i << endl
         << "&ir: " << &ir << endl
         << endl;
}();

然后输出看起来正确:

explicit value capture
i: 10
ir: 10
&i: 0x7fff0a5b5790
&ir: 0x7fff0a5b5794

这看起来越来越像一个错误。

2 个答案:

答案 0 :(得分:7)

这已在gcc-4.7 trunk和gcc-4.6分支中修复。 这些应该在gcc-4.7.0中提供(从现在起一段时间 - 仍处于第1阶段)和gcc-4.6.2(唉4.6.1刚出来。)

但是无畏的人可能会等待下一个快照或获得一个颠覆副本。

有关详细信息,请参阅audit trail

答案 1 :(得分:4)

使用VS 2010编译:

value capture
i: 10
ir: 10
&i: 0012FE74
&ir: 0012FE78

reference capture
i: 10
ir: 10
&i: 0012FF60
&ir: 0012FF60

对我来说看起来像个错误。