What does T::* signify in the declaration of a function parameter list?
what is the meaning of T::* inside the registration function declaration
This is the syntax of a pointer to member. Let's take a look at the whole type and name of the parameter:
void(T::*callback)(const pcl::visualization::KeyboardEvent&, void*)
This is the declaration of a variable named callback
. It's a pointer to member function. More precisely, it's a pointer to member function of the class T
.
If we take the name out of the type, we see things more clearly:
// class name ---v v------- parameters
void(T::*)(const pcl::visualization::KeyboardEvent&, void*)
// ^---- return type
It's in fact, a pointer to function member of the class T
that returns void
. It's a function that takes strictly two parameters: a const pcl::visualization::KeyboardEvent&
and a void*
.
why am I not allowed to pass this
It's simple. Look at the type of your function:
using func_type = decltype(keyboardEventCallback);
// hint: the type is: void(*)(const pcl::visualization::KeyboardEvent&, void*, void*)
Let's compare the two types side by side:
void(*)(const pcl::visualization::KeyboardEvent&, void*, void*)
void(T::*)(const pcl::visualization::KeyboardEvent&, void*)
First, your function is not a member function, it's a plain function pointer. It's not the same type. Then, you got three arguments, as the type of the parameter only ask for two. This is different.
Now, how can you fix this??
You could use a 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);
Or even simpler: just define keyboardEventCallback
inside your class, and send it:
// don't forget: keyboardEventCallback must receive the same parameter as asked.
m_vis->registerKeyboardCallback(&MyClass::keyboardEventCallback, *this, this);
This is the syntax for member functions.
Example:
class A{
int giveMe5();
};
&A::giveMe5; // will be of type int(A::*)()
Why does the type differ from free functions and static member functions ? Because member functions have an implicit parameter that points to the object on which the function gets called.
https://isocpp.org/wiki/faq/pointers-to-members#fnptr-vs-memfnptr-types says:
The type of this function is different depending on whether it is an ordinary function or a non-static member function of some class:
- Its type isint (*)(char,float)
if an ordinary function
- Its type isint (Fred::*)(char,float)
if a non-static member function of class Fred