views:

61

answers:

1

I'm trying to write a macro to make a specific usage of callbacks in C++ easier. All my callbacks are member functions and will take this as first argument and a second one whose type inherits from a common base class.

The usual way to go is:

register_callback(boost::bind(&my_class::member_function, this, _1));

I'd love to write:

register_callback(HANDLER(member_function));

Note that it will always be used within the same class.

Even if typeof is considered as a bad practice, it sounds like a pretty solution to the lack of __class__ macro to get the current class name.

The following code works:

typedef typeof(*this) CLASS;
boost::bind(& CLASS :: member_function, this, _1)(my_argument);

but I can't use this code in a macro which will be given as argument to register_callback.

I've tried:

#define HANDLER(FUN)                                           \
    boost::bind(& typeof(*this) :: member_function, this, _1);

which doesn't work for reasons I don't understand. Quoting GCC documentation:

A typeof-construct can be used anywhere a typedef name could be used.

My compiler is GCC 4.4, and even if I'd prefer something standard, GCC-specific solutions are accepted.

+1  A: 

Your problem might be that typeof yields my_class&. It appears to work with boost::remove_reference:

#include <boost/bind.hpp>
#include <boost/type_traits.hpp>
#include <iostream>

struct X
{
    void foo(int i) { std::cout << i << '\n'; }
    void bar() {boost::bind(&boost::remove_reference<typeof(*this)>::type::foo, this, _1)(10); }
};

int main()
{
    X x;
    x.bar();
}

It might be more portable to use BOOST_TYPEOF, and in C++0x decltype

UncleBens
Thank you. I'll have a closer look at Boost.TypeTraits, it looks like it's a clever answer to many template meta programming questions.
Warren Seine