tags:

views:

208

answers:

4

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

+3  A: 

Start from U, then work inside out.

The declared type is a pointer to a member function from class U taking void arguments and returning void.

Peter G.
But... `U` is a class, not a pointer. You mean, the parameter to `is_class_tester` is a pointer to a member function? That would make sense.
Aidan Cully
Note that here the type (of the method pointer) is not named (as it is in an error message). Thus in this case U is the name of the class from which the method is called.
Martin York
+10  A: 

* 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;
Victor Nicollet
+3  A: 

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)();
GMan
+3  A: 

It's a pointer to a member function of class U. it's quite similar to

void(*)(void)

but it points to a member function of class U.

MBZ