关于Lambda、函数指针转换及私有数据成员可见性的合规性疑问
哇,这个Lambda的用法确实有点反直觉但又完全合规!我刚用G和Clang验证了,你说的代码确实能正常编译,而且这完全符合C标准的要求。
为什么无捕获Lambda能访问类的私有成员?
- 首先,无捕获的Lambda可以隐式转换为对应的函数指针类型,你用
+只是显式触发了这个转换,本质上没改变Lambda的访问权限特性。 - 核心原因在于:如果这个Lambda是在类的成员函数(或者类的作用域内)定义的,它的访问权限是继承自定义它的上下文的——也就是说,它拥有和所在成员函数一样的访问权限,能访问类的私有/保护成员,行为就近似于类的静态成员函数(毕竟没有捕获任何实例,无法直接访问非静态成员,但可以通过传递实例指针的方式访问,或者直接访问静态私有成员)。
这个技巧的好用之处
你说要是早知道这个技巧就能避免一些麻烦,太对了!比如当你需要一个能访问类私有成员的回调函数,但又不想专门定义一个静态成员函数时,这个方式就特别便捷——代码更紧凑,不用额外写成员函数,还能保持对类内部成员的访问权限。
给你贴个简单的示例代码,一眼就能看明白:
class S { private: static int secret_static; int secret_instance; public: void demo() { // 访问静态私有成员的无捕获Lambda,转函数指针 auto static_access_fp = +[]() { S::secret_static = 42; }; static_access_fp(); // 访问实例私有成员的无捕获Lambda,通过传指针实现 auto instance_access_fp = +[](S* obj) { obj->secret_instance = 100; }; instance_access_fp(this); } }; int S::secret_static = 0;
这段代码在G++和Clang下都能顺利编译,转成的函数指针确实能访问S的私有成员,权限和静态成员函数完全一致。
顺便提一句:C++标准里明确规定,闭包类型的
operator()成员函数的访问权限,和Lambda定义时所在的上下文是相同的——这就是为什么无捕获Lambda即使转成函数指针,依然能拥有原上下文的访问权限。
内容的提问来源于stack exchange,提问作者skypjack
相关产品推荐
相关产品推荐

