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

Capturing reference variable by copy in C++0x lambda

本文关键字:引用 变量 复制 C++0x lambda      更新时间:2023-10-16

根据这个问题的答案和注释,当引用变量被值捕获时,lambda对象应该复制被引用对象,而不是引用本身。然而,GCC似乎并没有这么做。

使用以下测试:

#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;
}

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

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

这看起来越来越像一个bug。

这刚刚在gcc-4.7主干和gcc-4.6分支中得到修复。这些应该在gcc-4.7.0(一段时间后-仍处于第1阶段(和gcc-4.6.2(唉,4.6.1刚刚发布(中可用

但勇敢者可以等待下一个快照,或者获得一个subversion副本。

有关详细信息,请参阅审核跟踪。

使用VS 2010编译得到:

价值捕获i: 10ir:10&i: 0012页74&ir:0012FE78参考捕获i: 10ir:10&i: 0012FF60&ir:0012FF60

对我来说似乎是个错误。