C ++ 11 lambda可以访问我的私有成员。为什么?

时间:2014-06-16 06:28:14

标签: c++ gcc c++11 lambda clang

考虑这段代码:

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()
{
}

Live code (Clang)

Live code (GCC)

这对我来说似乎真的不直观。 C ++ 11/14标准对此有何看法?这是GCC / Clang的错误吗?

1 个答案:

答案 0 :(得分:11)

正如评论@Tony D@dyp已经回答:

§9.4.2/ 2静态数据成员[class.static.data]:

  

中的初始化表达式   static数据成员的定义属于其类的范围。

以上意味着static数据成员及其初始值设定者可以访问其班级的其他privateprotected成员。

同时考虑标准§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的私有成员。