从 cppinsights 我们看到下面的代码中
lambda();
行是如何被语言解释的:
const auto lambda = [] () mutable {};
void foo()
{
lambda();
}
有人会天真地认为,这一行调用了 lambda 的(非常量)
operator()
,而后者又无法编译。但是,编译器并没有这样做,而是将非捕获 lambda 转换为函数指针,调用函数指针,并接受代码。
此转换的目的是什么?对我来说,如果这被拒绝,那就更合乎逻辑了。没有迹象表明程序员有意进行这种转换。该语言自行完成此操作。
请注意,转换仅在上述情况下发生,其中调用
lambda.operator()()
会丢弃限定符。如果 operator()
不是 lambda
,或者 const
未标记为 operator()
,则不会发生这种情况(即直接调用 mutable
)。
将 lambda 声明为
mutable
意味着其 operator()
可以修改捕获的变量,这意味着 operator()
不能是 const
限定的。但是 lambda
是一个 const
对象,因此不能在其上调用非常量 operator()
(事实上,如果你尝试,编译器会报告错误)。
但是,非捕获 lambda 可以转换为函数指针,因此编译器就是这么做的。