考虑以下代码:
#include <iostream>
class foo {
int var = 99;
public:
static int const i;
};
int const foo::i = [&] { return foo().var; }();
auto main() -> int {
std::cout << foo::i << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
考虑标准§9.4.2/ 2静态数据成员[class.static.data]:
static数据成员定义中的初始化表达式属于其类的范围.
和
§5.1.2/ 2&3 Lambda表达式[expr.prim.lambda]:
2lambda表达式的评估导致prvalue临时(12.2).这个临时对象称为闭包对象.lambda表达式不应出现在未评估的操作数中(第5条).[注意:闭包对象的行为类似于函数对象(20.9).-结束注释]
3lambda-expression的类型(也是闭包对象的类型)是一个唯一的,未命名的nonunion类类型 - 称为闭包类型 - 其属性如下所述.此类类型不是聚合(8.5.1).闭包类型在包含相应lambda表达式的最小块作用域,类作用域或命名空间作用域中声明.
我们最终得出结论:表达式中的lambda:
int const foo::i = [&] { return foo().var; }();
Run Code Online (Sandbox Code Playgroud)
可以正确地访问private成员,class foo因为它是在static成员的初始化表达式中声明和定义i的class foo,因此其范围是其范围class foo …