What does T::* signify in the declaration of a function parameter list?
Asked Answered
N

2

6

I declare a particular keyboard callback function as this inside my code:

void keyboardEventCallback(const pcl::visualization::KeyboardEvent &event, void* viewer_void, void* widget_void);

The keyboard event is the actual event passed to the callback function, the viewer_void parameter is a pointer to a PCLVisualizer class that generates a window for rendering, and widget_void is a pointer to a widget that interfaces with Qt.

In the documentation for pcl, a registration function passes the arguments for registering the keyboard function like

boost::signals2::connection registerKeyboardCallback(void(T::*callback)(const pcl::visualization::KeyboardEvent&, void*), T& instance, void* cookie=nullptr)

So my question is, what is the meaning of T::* inside the registration function declaration, and why am I not allowed to pass this:

m_vis->registerKeyboardCallback(keyboardEventCallback, (void*)&m_vis, (void*)this);

where m_vis is a visualizer, keyboardcallback is the callback, and this is the widget.

Why can I not register like this. This is for the point cloud library.

Nary answered 19/10, 2016 at 15:48 Comment(0)
H
10

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);
Helluva answered 19/10, 2016 at 17:27 Comment(0)
I
4

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 is int (*)(char,float) if an ordinary function

- Its type is int (Fred::*)(char,float) if a non-static member function of class Fred

Intermix answered 19/10, 2016 at 16:2 Comment(1)
This is very valuable additional insight! It would be useful if you copy-pasted and quoted (with > my quote) the content of the link instead of just linking to it. Even a screenshot might be ok, although in this case quoting is best and not difficult.Slat

© 2022 - 2024 — McMap. All rights reserved.