C++11 无状态Lambda和私有成员

C++11 无状态Lambda和私有成员,c++11,lambda,private-members,C++11,Lambda,Private Members,在某些情况下,当使用C编写的涉及回调的库进行编程时,我喜欢使用Lambda表达式;然而,如果我需要改变类成员变量的状态,我不能将这个传递到无状态(函数指针)lambda中。但是我可以将这个分配给上下文结构中的数据。我觉得奇怪的是,即使它在类中是私有的,也能够访问该成员变量。 下面是我编写的示例代码,用于演示 #include <iostream> using std::cout; typedef struct extradatatype{ void* data; }extra

在某些情况下,当使用C编写的涉及回调的库进行编程时,我喜欢使用Lambda表达式;然而,如果我需要改变类成员变量的状态,我不能将
这个
传递到无状态(函数指针)lambda中。但是我可以将
这个
分配给上下文结构中的数据。我觉得奇怪的是,即使它在类中是私有的,也能够访问该成员变量。
下面是我编写的示例代码,用于演示

#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;
}
#包括
使用std::cout;
类型定义结构外部数据类型{
作废*数据;
}外部数据;
外部数据e={0};
typedef void(*回调)(额外数据*e);
无效cb(c){
c&e;
}
课堂测试{
私人:
int x;
公众:
测试(INTX){
这个->x=x;
}
void setcb(){
cb([](外部数据*e){
测试*self=重新解释(e->数据);
自我->x=20;
});
}
int getx(){
返回x;
}
};
int main(){
试验t(10);
e、 数据=&t;
t、 setcb();

CUT数据< /代码>但我可以访问代码>自-> x//> >,就像它是一个公共成员而不是私有的。所以我所困惑的是,lambda表达式表达式是在代码的/StcCb < /C>函数栈/上下文中执行的,或者它是作为它自己的函数在别处执行的,但是C++正在做一些奇怪的把戏来允许私有。te要访问的成员。因为我假设无状态lambda实际上与无法访问类的私有成员的非成员静态函数没有什么不同。

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

类示例{
私人:
int x;
公众:
int f(示例e){
返回e.x;
}
};
其中,由于
f
Example
的成员,它可以访问
e.x
,因为
e
具有类型
Example

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

外部无效(外部数据*e);
课堂测试{
私人:
int x;
公众:
void setcb(){
cb(外部);
}
};
外部无效(外部数据*e){
测试*self=重新解释(e->数据);
self->x=20;//此处出错!
}

setcb
内部的lambda与
setcb
本身具有相同的访问权限,并且可以做
setcb
可以做的任何事情。否则编写lambda会非常烦人。执行lambda的位置无关紧要-访问检查是在编译时执行的,而不是在运行时。为什么您认为lambda像一个非-具体来说,成员静态函数?为什么不能像成员静态函数一样(更接近现实)?静态成员函数将同时满足这两个属性-可以访问私有成员,并且可以作为C风格回调传递。@IgorTandetnik实际上是的。这是有道理的。它更像是一个成员静态函数,而不是非成员静态函数。我想,由于它是一个lambda,我不知何故相信它是在外部上下文中执行的类测试,因为我不能隐式使用
这个
哦,好吧,即使你传递了另一个类对象的指针,而不是它本身,它仍然可以访问私有成员,因为它是在类本身的上下文中执行的;所以它实际上是一个静态成员函数,不能使用
这个
,但它可以访问private Memberskin类似的,是的。如果您捕获它,它将能够使用
this
[this](…){…}
-这样
this
将在您的lambda中可用。当使用lambda代替函数指针时,您无法在上下文中捕获
this
test.cpp:32:11: error: 'int Test::x' is private within this context
     self->x = 20;
           ^