Declaring a method pointer with decltype in C ++

There are some differences between clangand gcc. One of them is how they interpret method pointers. Given the following code:

template <typename T_Class, typename T_Ret, typename ... Args>
void store_method(T_Class *object, T_Ret (T_Class::*method)(Args ... args));

class SomeObjectWithPotentiallyLongName {
     int commonly_used_method(int var);
     void register_method() {
          /* The code below is okay for gcc with -std=gnu++11. But clang
           * says:
           * 'reference to non-static member function must be called' */
          store_method(this, commonly_used_method);
          /* To make this fine for clang (and also - gcc), I have to 
           * extend previous line as next */
          store_method(this, &SomeObjectWithPotentiallyLongName::commonly_used_method);
     }
}

The above code shows the need to extend the code in many places to compile it with clang, while it can be very neat and straightforward with gcc.

The most obvious way is to write a macro that turns thisit method_nameinto something like that &TypeOfThis::method_name.

My idea was to use decltype:

#define STORE_METHOD(method) store_method(this, (decltype(*this))::method)

void SomeObjectWithPotentiallyLongName::register_method() {
     STORE_METHOD(commonly_used_method);
}

But this code gives the following error with clang:

'decltype (* this)' (aka 'SomeObjectWithPotentiallyLongName &') is not a class, namespace or enumeration

? , ?

+4
2

T & , ( , - ), . std::remove_reference<...>::type (documentation), T:

typedef std::remove_reference<decltype(*this)>::type T;

:

T::method
+3

& . decltype , std::decay, :

#define STORE_METHOD(method)\
    store_method(\
        this,\
        &std::decay<decltype(*this)>::type::method\
    )

std::decay_t ++ 14:

#define STORE_METHOD(method)\
    store_method(\
        this,\
        &std::decay_t<decltype(*this)>::method\
    )
+3

Source: https://habr.com/ru/post/1661176/


All Articles