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

Mar*_*cia 22 c++ lambda gcc clang c++11

考虑一下这段代码:

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()
{
}
Run Code Online (Sandbox Code Playgroud)

实时代码(Clang)

实时代码(GCC)

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

101*_*010 23

正如评论@Tony D@dyp中已经回答的那样:

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

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

以上意味着static数据成员及其初始化者可以访问其他private人和protected他们班级的成员.

同时考虑标准§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的prvalue临时闭包对象是static const数据成员的初始设定项中声明和定义的shy::object,因此lambda闭包对象的作用域是其范围class shy.因此,它可以访问私人成员class shy.