cpp*_*ast 20 c++ lambda const c++11 function-call-operator
我在下面的函数中有一个小的"lambda表达式":
int main()
{
int x = 10;
auto lambda = [=] () { return x + 3; };
}
Run Code Online (Sandbox Code Playgroud)
下面是为上面的lambda表达式生成的"匿名闭包类".
int main()
{
int x = 10;
class __lambda_3_19
{
public: inline /*constexpr */ int operator()() const
{
return x + 3;
}
private:
int x;
public: __lambda_3_19(int _x) : x{_x}
{}
};
__lambda_3_19 lambda = __lambda_3_19{x};
}
Run Code Online (Sandbox Code Playgroud)
由编译器生成的闭包"operator()"是隐式const.为什么标准委员会const默认做到这一点?
P.W*_*P.W 18
Herb Sutter在open-std.org上发现了这篇论文,讨论了这个问题.
奇怪的一对:按值注入const和
quirky mutable考虑这个稻草人示例,程序员通过值捕获局部变量并尝试修改捕获的值(这是lambda对象的成员变量):Run Code Online (Sandbox Code Playgroud)int val = 0; auto x = [=]( item e ) // look ma, [=] means explicit copy { use( e, ++val ); }; // error: count is const, need ‘mutable’ auto y = [val]( item e ) // darnit, I really can’t get more explicit { use( e, ++val ); }; // same error: count is const, need ‘mutable’此功能似乎是由于用户可能没有意识到他有副本而引起的,特别是因为lambdas是可复制的,所以他可能正在更改不同的lambda副本.
以上报价和例如指示为什么标准委员会可能使人们const在默认情况下并需要mutable去改变它.
除非
mutable在lambda表达式中使用了关键字,否则函数调用运算符是const限定的,并且由副本捕获的对象在此内部是不可修改的operator()
在您的情况下,通过副本捕获的任何内容都不可修改.
我想,如果你写的东西是
int x = 10;
auto lambda = [=] () mutable { x += 3; return x; };
Run Code Online (Sandbox Code Playgroud)
在const应该消失
- 编辑 -
OP精确
我已经知道添加mutable会解决问题.问题是我想了解默认情况下使lambda不可变的原因.
我不是语言律师,但这似乎是显而易见的:如果你operator()没有const,你就不能做出像
template <typename F>
void foo (F const & f)
{ f(); }
// ...
foo([]{ std::cout << "lambda!" << std::endl; });
Run Code Online (Sandbox Code Playgroud)
我的意思是......如果operator()不是const,你不能使用lambdas传递它们作为const参考.
如果不严格需要,应该是一个不可接受的限制.