C++ lambda friendship

C++ lambda friendship

本文关键字:friendship lambda C++      更新时间:2023-10-16

当lambda函数在函数F中声明时,该函数是类C的友元,该函数是否有权访问C的私有成员?具体来说,标准允许吗?

c++ 11§[expr.prim.]λ]5.1.2/3:

lambda表达式的类型(也是闭包对象的类型)是唯一的、未命名的非联合类类型——称为闭包类型——其属性将在下面描述。这个类类型不是聚合(8.5.1)。闭包类型在包含相应lambda表达式. ... 的最小块作用域、类作用域或命名空间作用域中声明。

因为闭包类型是在友元函数中声明的,所以每个§[类都有相同的访问权限。本地)9.8/1:

类可以在函数定义中声明;这样的类称为本地类。局部类的名称对于其封闭作用域是局部的。局部类位于封闭作用域的作用域中,并且与封闭函数. ...

具有对函数外部名称的相同访问权限。

嵌套类可以自动访问它的"所有者"可以访问的所有成员。你不需要lambdas就能看到:

class A {
  friend struct B;
  friend void g();
  static void f() { }
};
struct B {
  struct C {
    static void f() { A::f(); }
  };
  static void f() { C::f(); }
};
void g() {
  struct D {
    static void f() { A::f(); }
  };
  D::f();
}

尽管没有被明确地列为友元,C::fD::f可以调用私有的A::f而不会引起编译器的任何抱怨。

Lambdas是使用编译器生成的局部类实现的(这不仅仅是一个实现细节,这是标准所要求的),因此适用与其他局部类相同的规则。

局部类可以访问相同成员的规则在标准9.8中有详细说明:

局部类位于封闭作用域的作用域中,并且对函数外部的名称具有与封闭函数相同的访问权限。