C++ lambda 友谊

Posted

技术标签:

【中文标题】C++ lambda 友谊【英文标题】:C++ lambda friendship 【发布时间】:2014-05-23 17:06:07 【问题描述】:

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

【问题讨论】:

@RSahu 是的,但这不是确定代码是否合法的好策略。 @Anycorn 你在说什么,所有 C++ 编译器都 100% 符合 C++11 标准;) @0x499602D2 你在遵守讽刺方面做得如何? 根据定义,所有 C++ 编译器都符合标准。不符合标准的编译器不是 C++ 编译器(不管 Herb 怎么说!)。 @Casey 没有蛋糕。根据您的定义,也没有 c++11 编译器。没有蛋糕。 【参考方案1】:

C++11 §[expr.prim.lambda] 5.1.2/3:

lambda-expression 的类型(也是闭包对象的类型)是唯一的、未命名的非联合类类型——称为闭包类型——其属性如下所述。此类类型不是聚合 (8.5.1)。闭包类型在包含相应 lambda-expression 的最小块作用域、类作用域或命名空间作用域中声明。 ...

由于闭包类型是在友元函数中声明的,因此根据 §[class.local] 9.8/1 将具有相同的访问权限:

类可以在函数定义中声明;这样的类称为 local 类。本地类的名​​称在其封闭范围内是本地的。本地类在封闭作用域的范围内,并且对函数外部的名称具有与封闭函数相同的访问权限。 ...

【讨论】:

【参考方案2】:

嵌套类自动访问其“所有者”可以访问的所有成员。你不需要 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 而不会收到编译器的任何投诉。

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

9.8 标准中详细说明了本地类可以访问相同成员的规则:

本地类在封闭作用域的范围内,与封闭函数一样,对函数外的名称具有相同的访问权限。

【讨论】:

以上是关于C++ lambda 友谊的主要内容,如果未能解决你的问题,请参考以下文章

C++如何优雅地处理不被继承的友谊

三个人的友谊一定会有一个要退出吗?

“朋友”关系可以在 C++ 的类之间转移吗?

第三章社会理解力与友谊

友谊关系的最佳模型(在 Django 中)

国外友谊测试工具赚钱套路