通过 Lambda 访问私有成员函数

moe*_*ker 5 c++ lambda function-pointers callback

在一个项目中,我有一个 C-API,它使用 C 风格的函数指针作为回调。在其中一个回调中,我需要访问对象的私有函数Foo。请注意,API 调用是在我的类的函数内完成的。由于未显示代码,我有一个对象的句柄可供void*我访问。

除了构造容易出错之外,通过传递 lambda 作为回调,我可以访问对象的私有函数。这有点出乎我的意料,但对我来说很受欢迎。我还没有发现任何有关此行为的信息,所以我想请问是否有人可以解释为什么这是实际工作的。我不知道 lambda 正在捕获某些内容,但看起来这与实际的作用域有关。我正在使用 C++17 和 gcc 10.2。

这是一个示例代码块:

void TestFunc(void (*)(void*)) {
}

class Foo {
public:
    Foo() {
     TestFunc([](void* handle){
         auto foo = reinterpret_cast<Foo*>(handle);
         foo->BarFunc();
     });
    };
private:
    void BarFunc() {};
};
Run Code Online (Sandbox Code Playgroud)

ixS*_*Sci 4

您的代码正在运行,因为标准允许它。首先我们有这个(C++20 [expr.prim.lambda.closure]p2):

闭包类型在包含相应 lambda 表达式的最小块作用域、类作用域或命名空间作用域中声明。<...>

在您的示例中,我们有一个块作用域,因此最后我们有一个未命名的本地类声明,根据[class.local]p1:

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