我在我的代码中声明了一个特定的键盘回调函数:
void keyboardEventCallback(const pcl::visualization::KeyboardEvent &event, void* viewer_void, void* widget_void);
键盘事件是传递给回调函数的实际事件,viewer_void参数是指向PCLVisualizer类的指针,该类生成用于呈现的窗口,而widget_void是指向与Qt接口的窗口小部件的指针。
在pcl的文档中,注册函数传递用于注册键盘函数的参数,如
boost::signals2::connection registerKeyboardCallback(void(T::*callback)(const pcl::visualization::KeyboardEvent&, void*), T& instance, void* cookie=nullptr)
所以我的问题是,注册函数声明中T::*
的含义是什么,为什么我不允许传递这个:
m_vis->registerKeyboardCallback(keyboardEventCallback, (void*)&m_vis, (void*)this);
其中m_vis
是可视化工具,keyboardcallback
是回调,这是小工具。
为什么我不能这样注册。这是针对点云库的。
答案 0 :(得分:5)
注册函数声明中的T :: *是什么意思
这是指向成员的指针的语法。我们来看看参数的整个类型和名称:
void(T::*callback)(const pcl::visualization::KeyboardEvent&, void*)
这是名为callback
的变量的声明。它是指向成员函数的指针。更确切地说,它是指向类T
的成员函数的指针。
如果我们从名称中取出名称,我们会更清楚地看到事情:
// class name ---v v------- parameters
void(T::*)(const pcl::visualization::KeyboardEvent&, void*)
// ^---- return type
事实上,它是指向返回T
的类void
的函数成员的指针。它是严格两个参数的函数:const pcl::visualization::KeyboardEvent&
和void*
。
为什么我不允许通过这个
很简单。看看你的功能类型:
using func_type = decltype(keyboardEventCallback);
// hint: the type is: void(*)(const pcl::visualization::KeyboardEvent&, void*, void*)
让我们并排比较两种类型:
void(*)(const pcl::visualization::KeyboardEvent&, void*, void*)
void(T::*)(const pcl::visualization::KeyboardEvent&, void*)
首先,你的函数不是一个成员函数,它是一个普通的函数指针。它的类型不一样。然后,你有三个参数,因为参数的类型只要求两个。这是不同的。
现在,你怎么解决这个问题?
你可以使用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);
甚至更简单:只需在您的课程中定义keyboardEventCallback
,然后发送:
// don't forget: keyboardEventCallback must receive the same parameter as asked.
m_vis->registerKeyboardCallback(&MyClass::keyboardEventCallback, *this, this);
答案 1 :(得分:1)
这是成员函数的语法。
示例:
class A{
int giveMe5();
};
&A::giveMe5; // will be of type int(A::*)()
为什么类型与自由函数和静态成员函数不同? 因为成员函数有一个隐含参数,该参数指向调用函数的对象。
查看:https://isocpp.org/wiki/faq/pointers-to-members#fnptr-vs-memfnptr-types