无状态Lambda和私人成员

时间:2019-06-26 02:03:00

标签: c++11 lambda private-members

在某些情况下,当使用用C语言编写的涉及回调的库进行编程时,我喜欢使用Lambda表达式。但是,如果需要更改类成员变量的状态,则无法突出显示this到无状态(函数指针)lambda中。但是我可以将this分配给上下文结构中的数据。我发现奇怪的是,即使该成员变量在类中是私有的,也能够访问该成员变量。 这是我编写来演示的示例代码。

#include <iostream>
using std::cout;
typedef struct extradatatype{
    void* data;
}extradata;
extradata e = {0};
typedef void(*callback)(extradata* e);
void cb(callback c){
    c(&e);
}

class Test{
private:
    int x;
public:
    Test(int x){
        this->x = x;
    }
    void setcb(){
        cb([](extradata* e){
            Test* self = reinterpret_cast<Test*>(e->data);
            self->x = 20;
        });
    }

    int getx(){
        return x;
    }
};

int main(){
    Test t(10);
    e.data = &t;
    t.setcb();
    cout << t.getx();

    return 0;
}

在Lambda表达式中,Test* self被分配给e->data,但我可以访问self->x,就好像它是公共成员而不是私有成员一样。所以我很困惑的是,lambda表达式是在setcb函数的堆栈/上下文中执行还是在其他地方作为其自己的函数执行,但是C ++在做一些怪异的技巧来允许私有成员被访问。因为我假设无状态的lambda实际上与无法访问类的私有成员的非成员静态函数没有什么不同。

1 个答案:

答案 0 :(得分:1)

由于您的lambda函数是在类Test的上下文中定义的,因此可以访问类Test的私有成员(无论是this.x还是self.x,其中{{ 1}}的类型为self)。类似于以下示例:

Test

其中,由于class Example { private: int x; public: int f(Example e) { return e.x; } }; f的成员,因为Example的类型为e.x,所以它可以访问e

如果将lambda函数定义移出类上下文,则会看到预期的错误消息:

Example
void outside(extradata* e);

class Test{
private:
    int x;
public:
    void setcb(){
        cb(outside);
    }
};

void outside(extradata* e) {
    Test* self = reinterpret_cast<Test*>(e->data);
    self->x = 20;  // error here!
}