据说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; };
}
Run Code Online (Sandbox Code Playgroud)
输出:
foo()
Run Code Online (Sandbox Code Playgroud)
为什么我得到foo()但没有得到:
foo()
foo()
in un-named lambda x: 1024
Run Code Online (Sandbox Code Playgroud)
[x = foo()]初始化并且{x = foo()}是赋值?因此,您的代码有两个问题:
int x = 0;
这x是永远不会使用。见下文
[x = foo()]
这不捕捉变量x在main。相反,它是广义的lambda捕获。如果你要觉得在类类型相当于拉姆达的条款,它创建了一个名为成员x初始化所用foo()。同样,绝对与xmain中的变量没有关系。
[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()};
;
}
Run Code Online (Sandbox Code Playgroud)
另外,请启用并注意您的警告:为什么我应该始终启用编译器警告?
Run Code Online (Sandbox Code Playgroud)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。