How to remove decltype(&MyClass::funct) part by extending the following type traits?

(Answer archived for future visitors; this solution requires C++17!)


You're really close!

The trick is auto template arguments, and the fact that pointers-to-members can be used as template arguments, like so:

template <auto thing>
using class_t = get_class_t<decltype(thing)>;

int main()
{
    class_t<&MyClass::funct> myObj;
    myObj.funct();
}

Of course if you can write this then you already know the type so you'd just write MyClass, so that's not very useful.

Sadly you won't be able to make it accept ptr as a template argument, though; you're stuck with get_class_t for that:

int main()
{
    auto ptr = &MyClass::funct;
    get_class_t<decltype(ptr)> myObj;
    myObj.funct();
}

(live demo)

In the latter case, a nice type alias can help you a bit:

auto ptr = &MyClass::funct;

using ClassType = get_class_t<decltype(ptr)>;
ClassType myObj;

myObj.funct();

(live demo)

Personally I think this level of verbosity is pretty reasonable.


You can provide a function which will create required object. This is very simple to achieve:

template<typename T, typename ...Args>
auto makeObjectForMethod(T&&, Args&& ...args) -> get_class_t<decltype(&MyClass::funct)>
{
    using R = get_class_t<decltype(&MyClass::funct)>;
    return R{ std::forward(args)... };
}

int main()
{
    auto myObj = makeObjectForMethod(&MyClass::funct);

    myObj.funct();
    return 0;
}

Works with C++11 and is quite handy: https://wandbox.org/permlink/usMa3fA0I2HCNJ7M

The only disadvantage that in case of class fields it is not very helpful.