考虑这段代码:
class shy {
private:
int dont_touch; // Private member
public:
static const shy object;
};
const shy shy::object = []{
shy obj;
obj.dont_touch = 42; // Accessing a private member; compiles; WHY?
return obj;
}();
int main()
{
}
这对我来说似乎真的不直观。 C ++ 11/14标准对此有何看法?这是GCC / Clang的错误吗?
答案 0 :(得分:11)
§9.4.2/ 2静态数据成员[class.static.data]:
中的初始化表达式
static
数据成员的定义属于其类的范围。
以上意味着static
数据成员及其初始值设定者可以访问其班级的其他private
和protected
成员。
同时考虑标准§5.1.2/ 2& 3 Lambda表达式[expr.prim.lambda]:
2
对lambda表达式的求值导致prvalue临时(12.2)。这个临时对象称为闭包对象。 lambda表达式不应出现在未评估的操作数中(第5条)。 [注意:闭包对象的行为类似于函数对象(20.9).- end note]
3
lambda-expression的类型(也是闭包对象的类型)是一个唯一的,未命名的nonunion类类型 - 称为闭包类型 - 其属性如下所述。此类类型不是聚合(8.5.1)。闭包类型在包含相应lambda表达式的最小块作用域,类作用域或命名空间作用域中声明。
结合上述内容,我们最终得出结论: lambda的prvalue临时闭包对象在static
const
数据成员的初始值设定项中声明和定义{ {1}}因此 lambda的闭包对象的范围是shy::object
的范围。因此它可以访问class shy
的私有成员。