对于我的一个项目,我使用GLFW3。我试着给函数GLFWSetKeyCallback一个c11 lambda,它把一个GFLWwindow和一个GLFWfunkey函数作为参数,这是一个要作废的typedef(*GLFWkeyfun)(GLFWwindow*,int,int,int,int)。
该函数是从我的窗口类调用的,下面是代码
window.hpp
class Window
{
public:
Window(GLuint width, GLuint height, std::string title);
~Window();
GLFWwindow* get() { return window_.get(); }
bool is_open() { return open_; };
void close();
private:
bool open_ = false;
std::unique_ptr<GLFWwindow, DestroyWindow> window_;
std::vector<Drawable*> drawables_;
};
还有window.cpp
#include <pck/window.hpp>
Window::Window(GLuint width, GLuint height, std::string title) :
open_(true)
{
window_.reset(glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr));
glfwMakeContextCurrent(window_.get());
Global::width = width;
Global::height = height;
glfwSetKeyCallback(window_.get(), [this](GLFWwindow* window, int key, int scancode, int action, int mode){
for(auto it : drawables_)
it->input(window, key, scancode, action, mode);
});
}
Window::~Window()
{
window_.reset();
}
void
Window::close()
{
open_ = false;
window_.reset();
}
和来自编译器的错误(clang 3.8.1)
fatal error: no matching function for call to 'glfwSetKeyCallback'
glfwSetKeyCallback(window_.get(), [this](GLFWwindow* window, i...
^~~~~~~~~~~~~~~~~~
/usr/include/GLFW/glfw3.h:3307:20: note: candidate function not viable: no
known conversion from '(lambda at
/path/to/file.cpp)' to
'GLFWkeyfun' (aka 'void (*)(GLFWwindow *, int, int, int, int)') for 2nd argument
GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun);
有人能指出我做错了什么吗?
谢谢
只有具有空捕获列表的lambdas可以转换为普通的旧函数指针。
所以,问题是
[this]
而不是
[]
但是如果你需要一个有状态的回调,那么你就不走运了。据我所知,这是不可能的,反正没有邪恶的体操是不行的。
也就是说,大多数C API提供了一个上下文指针,允许回调实际接收它应该工作的状态。似乎窗口
参数就是您的示例中的参数。
无法将具有捕获的lambda转换为函数指针。函数指针是无状态的,它指向函数。具有捕获的lambda具有状态。它的行为就像一个物体。如果没有实例,则无法调用成员函数。这就是带有捕获的lambda不能转换为函数指针的方式。
您必须将函数更改为:
glfwSetKeyCallback(window_.get(), [](GLFWwindow* window, int key, int scancode, int action, int mode){ /* ... */ });
但是,您可以绕过无法访问此内容的限制。GLFW给了我们一种传递状态的方法。结构GLFWWindow
包含一个可以自由更改和访问的无效*
成员。
您可以这样做:
// Here we are setting the user pointer to `this`
glfwSetWindowUserPointer(window_.get(), this);
glfwSetKeyCallback(window_.get(), [](GLFWwindow* window, int key, int scancode, int action, int mode){
// Here we retrieve the pointer we setted before. It will be equal to `this`
auto& self = *static_cast<Window*>(glfwGetWindowUserPointer(window));
for(auto&& it : self.drawables_) {
it->input(window, key, scancode, action, mode);
}
});
正如krzaq所说,如果想要函数指针,就不能使用闭包。因此,您不能像您的示例中那样捕获。
如果您仍然需要
此
,则可以将其与GLFWwindow
关联。我知道您可以使用以下API:glfwSetWindowUserPointer将GLFWwindow实例与窗口
类的实例相关联。然后在回调中,您可以使用:glfwGetWindowUserPointer检索它。
所以你的代码看起来像(伪代码):
glfwSetWindowUserPointer(window_.get(), this);
glfwSetKeyCallback(window_.get(), [](GLFWwindow* window, int key, int scancode, int action, int mode){
Window* pw = (Window*)glfwGetWindowUserPointer(window);
for(auto it : pw->drawables_)
it->input(window, key, scancode, action, mode);
});
我按照以下说明创建AWS Lambda层: 然后我压缩文件夹“python”()并将其上传到s3。这是我解压文件夹进行双重检查时看到的:
如果我不使用' a '和' b '变量,一切正常,否则,C返回: 错误:无法转换“main()::” 注意:初始化'void f(int, void(*)(int))'的参数2
我有一个简单的Micronaut Lambda应用程序,很难成功地将Mocks注入到我的单元测试中。 build.gradle 具有以下基本控制器 以及以下测试类别: 上面的测试将失败,因为模拟从未与之交互。 调试时,我可以看到在测试类本身中被模拟,但在类中使用了一个实际的对象。 我注意到,当我不使用(例如)时,这是预期的,所以我认为这与Lambda运行时有关,我希望有人能够指出我在正确的方向上。
我是Kotlin的新手,很难理解下面的代码 所以这个函数叫做,它的输入参数是一个名为的函数,它是
问题内容: 我有一张包含键和值的地图。我需要使用以下特定格式将其转换为。现在,我用来格式化每个元素,将它们收集到一个List中,然后执行String.join();。 有什么更短的方法吗?使用lambda会很好,因为我需要一些使用lambda的练习。 问题答案: 我认为您正在寻找这样的东西: 依次进行以下操作: 获取一个可迭代的条目序列 为此迭代创建一个流 将该条目流转换为“键-值”形式的字符串流
我试图编写一个接受两个参数的函数,和。然后,它应该按照中给出的顺序对进行排序。例如,如果是,是,则函数应返回,排序中的顺序元素。 我按照下面的方式编写代码,但在arrays.sort处不断出现错误。我想我没有正确地使用lambda。你能具体说明我做错了什么吗?