Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does void(U::*)(void) mean?

Tags:

c++

templates

I was looking at the implementation of the is_class template in Boost, and ran into some syntax I can't easily decipher.

    template <class U> static ::boost::type_traits::yes_type is_class_tester(void(U::*)(void));
    template <class U> static ::boost::type_traits::no_type is_class_tester(...);

How do I interpret void(U::*)(void) above? I'm familiar with C, so it appears somewhat analogous to void(*)(void), but I don't understand how U:: modifies the pointer. Can anyone help?

Thanks

like image 684
Aidan Cully Avatar asked Jul 19 '10 12:07

Aidan Cully


2 Answers

* indicates a pointer, because you can access its contents by writing *p. U::* indicates a pointer to a member of class U. You can access its contents by writing u.*p or pu->*p (where u is an instance of U).

So, in your example, void (U::*)(void) is a pointer to a member of U that is a function taking no arguments and returning no value.

Example:

class C { void foo() {} };

typedef void (C::*c_func_ptr)(void);

c_func_ptr myPointer = &C::foo;
like image 167
Victor Nicollet Avatar answered Oct 09 '22 16:10

Victor Nicollet


You're right, it is analogous to a function pointer. Rather, this is a pointer to member function, where the member is of the class U.

The difference in type is necessitated because member functions have an implicit this pointer, as they cannot be called without an instance. Getting rid of the template might make it a bit easier:

struct foo
{
    void bar(void);
};

void(*)(void) won't do, as this has no way to communicate an instance of the class. Rather, we need:

void (foo::*)(void)

Indicating that this function pointer requires an instance of foo.


For what it's worth, you use them like this:

typedef void (foo::*func_ptr)(void);

foo f;
foo* fp = &f;
func_ptr func = &foo::bar;

(f.*func)();
(fp->*func)();
like image 41
GManNickG Avatar answered Oct 09 '22 16:10

GManNickG