Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 406
wfehrnstrom Avatar asked Oct 19 '16 15:10

wfehrnstrom


People also ask

What is the parameters in function declaration?

The function declarator includes the list of parameters that can be passed to the function when it is called by another function, or by itself. In C++, the parameter list of a function is referred to as its signature. The name and signature of a function uniquely identify it.

What is the parameter list of a function?

The parameter list of a function describes the number and types of the arguments that the function accepts, and the number and types of the values it returns. The parameter list of a generic function is used to define the overall protocol of the generic function.

What is *& Means in a function parameter?

It means a reference to a pointer to an int. In other words, the function can change the parameter to point to something else. To pass a variable in, just pass an int*. As awoodland points out, what's passed in must be an l-value.

What is the parameter list in C++?

The parameter list refers to the type, order, and number of the parameters of a function. Parameters are optional; that is, a function may contain no parameters. Function Body − The function body contains a collection of statements that define what the function does.


2 Answers

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);
like image 126
Guillaume Racicot Avatar answered Oct 29 '22 00:10

Guillaume Racicot


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

like image 44
AF_cpp Avatar answered Oct 29 '22 02:10

AF_cpp