void.pointer
void.pointer

Reputation: 26365

How can I use decltype to get the address of some class type's member function?

Suppose the following code:

class MyTest
{
public:

    void CallFoo()
    {
    }

    MyTest()
    {
        std::function<void()> func = &decltype(*this)::CallFoo;
    }
};

int main()
{
    MyTest t;
}

What I have there won't compile, but essentially I need to be able to use decltype to get the address to a member function of the type of *this. Normally you'd just do &MyTest::CallFoo.

Is this possible? If so, what is the correct syntax?

Upvotes: 0

Views: 298

Answers (2)

Neil Kirk
Neil Kirk

Reputation: 21773

Warning: Contains a macro. Use responsibly.

Use the following macro to make decltype work "sensibly" with references.

template<class T> struct TypeOf { typedef typename std::remove_reference<T>::type type; };
#define TYPE(x) TypeOf<decltype(x)>::type

Upvotes: 0

Brian Bi
Brian Bi

Reputation: 119194

You can do

&std::remove_pointer_t<decltype(this)>::CallFoo

or in C++11 (sorry, just noticed tag)

&std::remove_pointer<decltype(this)>::type::CallFoo

The problem with what you have is that decltype(*this) gives MyTest& rather than MyTest since *this is an lvalue.

However, std::function<void()> won't work, since a non-static member function of MyTest needs to be called with a MyTest* to act as this. You can use std::function<void(MyTest*)> or std::function<void(decltype(this))> if you want the caller to specify the object. If you want to bind this, you should probably just use a lambda, it's much easier:

auto func = [this]{ CallFoo(); };

Upvotes: 7

Related Questions