use*_*261 4 c++ qt callback void point-cloud-library
我在我的代码中声明了一个特定的键盘回调函数:
void keyboardEventCallback(const pcl::visualization::KeyboardEvent &event, void* viewer_void, void* widget_void);
Run Code Online (Sandbox Code Playgroud)
键盘事件是传递给回调函数的实际事件,viewer_void参数是指向PCLVisualizer类的指针,该类生成用于呈现的窗口,而widget_void是指向与Qt接口的窗口小部件的指针.
在pcl的文档中,注册函数传递用于注册键盘函数的参数
boost::signals2::connection registerKeyboardCallback(void(T::*callback)(const pcl::visualization::KeyboardEvent&, void*), T& instance, void* cookie=nullptr)
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,注册函数声明中的含义T::*是什么,为什么我不允许传递这个:
m_vis->registerKeyboardCallback(keyboardEventCallback, (void*)&m_vis, (void*)this);
Run Code Online (Sandbox Code Playgroud)
m_vis可视化器在哪里,keyboardcallback是回调,这是小部件.
为什么我不能这样注册.这是针对点云库的.
注册函数声明中T ::*的含义是什么?
这是指向成员的指针的语法.我们来看看参数的整个类型和名称:
void(T::*callback)(const pcl::visualization::KeyboardEvent&, void*)
Run Code Online (Sandbox Code Playgroud)
这是名为变量的声明callback.它是指向成员函数的指针.更准确地说,它是指向类的成员函数的指针T.
如果我们从名称中取出名称,我们会更清楚地看到事情:
// class name ---v v------- parameters
void(T::*)(const pcl::visualization::KeyboardEvent&, void*)
// ^---- return type
Run Code Online (Sandbox Code Playgroud)
它实际上是一个指向T返回类的函数成员的指针void.这是一个严格要求两个参数的函数:a const pcl::visualization::KeyboardEvent&和a void*.
为什么我不允许通过这个
这很简单.看看你的功能类型:
using func_type = decltype(keyboardEventCallback);
// hint: the type is: void(*)(const pcl::visualization::KeyboardEvent&, void*, void*)
Run Code Online (Sandbox Code Playgroud)
让我们并排比较两种类型:
void(*)(const pcl::visualization::KeyboardEvent&, void*, void*)
void(T::*)(const pcl::visualization::KeyboardEvent&, void*)
Run Code Online (Sandbox Code Playgroud)
首先,你的函数不是一个成员函数,它是一个普通的函数指针.它不是同一类型.然后,你有三个参数,因为参数的类型只要求两个.这是不同的.
现在,你怎么解决这个问题?
你可以使用lambda:
auto myCallback = [](const pcl::visualization::KeyboardEvent& e, void* c) { /* ... */ }
using lambdaType = decltype(myCallback);
// Be careful here, we don't want our lambda to go out of scope when it is called.
m_vis->registerKeyboardCallback(&lambdaType::operator(), myCallback, this);
Run Code Online (Sandbox Code Playgroud)
甚至更简单:只需keyboardEventCallback在类中定义,然后发送:
// don't forget: keyboardEventCallback must receive the same parameter as asked.
m_vis->registerKeyboardCallback(&MyClass::keyboardEventCallback, *this, this);
Run Code Online (Sandbox Code Playgroud)