C++ GLFW lambdas可以接受捕获参数吗?

C++ GLFW lambdas可以接受捕获参数吗?,c++,lambda,glfw,C++,Lambda,Glfw,我正在创建一个GLFWKeyCallback,由于它非常简单,我决定使用lambda。这个回调修改了一个成员变量,因此我必须将它传递到捕获列表中。到目前为止,我的代码是这样的: glfwSetKeyCallback(window, [this](GLFWwindow* window, int key, int scancode, int action, int mods) { if(action == GLFW_PRESS)

我正在创建一个GLFWKeyCallback,由于它非常简单,我决定使用lambda。这个回调修改了一个成员变量,因此我必须将它传递到捕获列表中。到目前为止,我的代码是这样的:

glfwSetKeyCallback(window, 
        [this](GLFWwindow* window, int key, int scancode, int action, int mods)
        {
            if(action == GLFW_PRESS)
            {
                 //use a mutex
                 //Modify member variable
            }
        });
问题在于,每当我将此传递到捕获列表时,Visual Studio 2019都会显示以下错误:

不存在从“lambda[]void(GLFWwindow*窗口,int键,int扫描码,int操作,int mods)->void”到GLFWKeyfun“的合适转换函数


我是否遗漏了什么,或者这段代码无效?

GLFW回调不接受lambda或函数对象:它们接受普通的旧函数指针。非捕获lambda可以转换为函数指针,但不能转换为捕获lambda

但是,使用
glfwSetUserPointer
glfwSetUserPointer
可以获得类似的效果。lambda仍然无法捕获,但可以恢复
指针

比如说,

struct MyClass{
GLFWwindow*窗口;
MyClass(GLFWwindow*window):窗口(window){
glfwSetWindowUserPointer(窗口,静态_转换(this));
glfwSetKeyCallback(窗口,
[](GLFWwindow*窗口,int键,int扫描码,int操作,int mods){
auto self=static_cast(glfwGetWindowUserPointer(窗口));
//可以通过“self”访问成员变量`
});
}
//确保其中一个类的持续时间与GLFW的持续时间相同
//或者清理此处的用户指针和回调
~MyClass(){
//清理
}
//可能你不能复制,否则会发生坏事
MyClass(常量MyClass&)=删除;
MyClass&运算符=(const MyClass&)=删除;
//其他事情。。。
};

GLFW回调不采用lambda或函数对象:它们采用普通的旧函数指针。非捕获lambda可以转换为函数指针,但不能转换为捕获lambda

但是,使用
glfwSetUserPointer
glfwSetUserPointer
可以获得类似的效果。lambda仍然无法捕获,但可以恢复
指针

比如说,

struct MyClass{
GLFWwindow*窗口;
MyClass(GLFWwindow*window):窗口(window){
glfwSetWindowUserPointer(窗口,静态_转换(this));
glfwSetKeyCallback(窗口,
[](GLFWwindow*窗口,int键,int扫描码,int操作,int mods){
auto self=static_cast(glfwGetWindowUserPointer(窗口));
//可以通过“self”访问成员变量`
});
}
//确保其中一个类的持续时间与GLFW的持续时间相同
//或者清理此处的用户指针和回调
~MyClass(){
//清理
}
//可能你不能复制,否则会发生坏事
MyClass(常量MyClass&)=删除;
MyClass&运算符=(const MyClass&)=删除;
//其他事情。。。
};


glfwSetKeyCallback
不接受lambda-它接受一个普通的旧函数指针。无捕获的lambda可以转换为函数指针;有捕获的lambda不能(没有存储捕获数据的位置)。这回答了你的问题吗?。我的回答显示了在调用裸函数的情况下使用成员函数的混乱性质。你可以使用
glfwSetWindowUserPointer
为窗口提供用户定义的指针(就像
这个
是什么)然后使用
glfwGetWindowUserPointer
从回拨中取回它我刚刚完成了一个答案,演示了
glfwSetWindowUserPointer
当问题结束时:(不过,是的,设置和检索
是正确的方法,因为窗口指针是正确的方法。我的答案显示了解决问题的方法。重点是,您需要一个类的实例来更改成员变量。带有捕获的lambda永远不会工作——它是一个使用函数指针和捕获值动态创建的类作为数据成员使用。
glfwSetKeyCallback
不接受lambda-它接受普通的旧函数指针。无捕获的lambda可转换为函数指针;有捕获的lambda则不能(没有存储捕获数据的位置)。这回答了你的问题吗?。我的回答显示了在调用裸函数的情况下使用成员函数的混乱性质。你可以使用
glfwSetWindowUserPointer
为窗口提供用户定义的指针(就像
这个
是什么)然后使用
glfwGetWindowUserPointer
从回拨中取回它我刚刚完成了一个答案,演示了
glfwSetWindowUserPointer
当问题结束时:(不过,是的,设置和检索
是正确的方法,因为窗口指针是正确的方法。我的答案显示了解决问题的方法。重点是,您需要一个类的实例来更改成员变量。带有捕获的lambda永远不会工作——它是一个使用函数指针和捕获值动态创建的类作为数据成员使用。我如何销毁用户指针?还有,为什么不能复制对象?@SuperSim135要清理,只需将用户指针设置回
nullptr
或其他任何位置,回调也是如此。对象不应可复制的原因是,用户指针实际上是一个全局变量-只能使用一次r指针。因此,拥有多个类是有问题的。(也就是说,回顾这一点,我忽略了提到每个
GLFWwindow*
实例可以有一个单独的用户指针。该类仍然不应该是可复制的,但可以有多个类实例来处理,例如多个窗口。)你的答案有一个问题,那就是它只允许访问可公开访问的成员。我认为我真正的解决方案是简单地使用另一个API或简化我的程序结构。GLFW可能不是