据说,lambda的成员是在定义lambda时初始化的,而不是在创建该lambda的对象时初始化的。为了进一步理解这一点,我制作了一个函数foo
,该函数打印一条简单的消息(稍后检查),并返回一个用于初始化lambda成员的整数值(任意值,此处为1024)。
在lambda主体内部,它会打印其捕获对象的值。
int foo() {
std::cout << "foo()" << std::endl;
return 1024;
}
int main() {
int x = 0;
[x = foo()]()mutable{ x = foo(); cout << "in un-named lambda x: " << x << endl; };
}
输出:
foo()
为什么我只有foo()
却没有得到
foo()
foo()
in un-named lambda x: 1024
[x = foo()]
是初始化并且在{x = foo()}
中是赋值?答案 0 :(得分:5)
因此,您的代码有几个问题:
int x = 0;
此x
从未使用过。见下文
[x = foo()]
这不会捕获x
中的变量main
。而是a generalized lambda capture。如果要考虑与lambda等效的类类型的术语,它将创建一个名为x
的成员,该成员初始化为foo()
。再次与main中的变量x
完全没有联系。
[x = foo()]()mutable{ x = foo(); cout << "in un-named lambda x: " << x << endl; };
最后,您的lambda永远不会被调用。因此,{ x = foo(); cout << "in un-named lambda x: " << x << endl; }
永远不会执行。
有一个很棒的工具,可让您查看编译器对代码的转换方式:https://cppinsights.io/s/cd26f632
#include <iostream>
int foo()
{
std::operator<<(std::cout, "foo()").operator<<(std::endl);
return 1024;
}
int main()
{
int x = 0;
class __lambda_12_5
{
int x;
public:
inline /*constexpr */ void operator()()
{
x = foo();
std::operator<<(std::cout, "in un-named lambda x: ").operator<<(x).operator<<(std::endl);
}
public: __lambda_12_5(int _x)
: x{_x}
{}
} __lambda_12_5{foo()};
;
}
还请启用并注意您的警告:Why should I always enable compiler warnings?
source>:12:5: warning: expression result unused [-Wunused-value] [x = foo()]()mutable{ x = foo(); std::cout << "in un-named lambda x: " << x > << std::endl; }; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~> ~~~~~~~~~~ <source>:11:9: warning: unused variable 'x' [-Wunused-variable] int x = 0; ^ 2 warnings generated.
如您所见,您将被告知未使用的变量和未调用的lambda。