根据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
这看起来越来越像一个错误。
答案 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
对我来说看起来像个错误。