Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I wanted to have type traits which will help me to get the type of the class from a member function pointer. I looked into this answer and found my half way to the aim.

It looks like this:

#include <iostream>

// example class
struct MyClass {
    void funct() { std::cout << "funct has been called....\n"; }
};

// traits
template<typename Class> struct get_class{};
template<typename ReType, typename Class, typename... Args>
struct get_class<ReType(Class::*)(Args...)>
{
    using type = Class;
};
template<typename Type> using get_class_t = typename get_class<Type>::type;

int main()
{
    get_class_t<decltype(&MyClass::funct)> myObj;
    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---> this is a lot of typing
    myObj.funct();
    return 0;
}

But, as shown in the code I need every time to write get_class_t<decltype(&MyClass::funct)> or in the case of

  auto ptr =  &MyClass::funct;
  get_class_t<decltype(ptr)> myObj;
  //         ^^^^^^^^^^^^^^

which is a lot of decltype()ing. I would like to write instead

class_t<ptr> obj;
or
class_t<&MyClass::funct> myObj;

which is more convenient.

I did the following function, which will return a resulting object of the class and maybe I could do, want I wanted to.

template<typename Type>
auto helper_function(Type ptr)->get_class_t<Type>
{
    return get_class_t<Type>{};
}

template<typename Type>
using class_t = /* decltype(helper_function(Type ptr));*/ 
//             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // what could be here?

I do not know how to complete this. My goal is to extend the traits in such a way that I could create an object like

auto ptr = &MyClass::funct;
class_t<ptr> myObj;
// or
class_t<&MyClass::funct> myObj;

Is there any other way to do this? or should I have to stick with decltype()ing?

As I have tagged, I would like to see whether it possible with C++11?

like image 875
User Using Avatar asked May 13 '19 10:05

User Using


People also ask

What is the difference between auto and decltype Auto?

auto is a keyword in C++11 and later that is used for automatic type deduction. The decltype type specifier yields the type of a specified expression. Unlike auto that deduces types based on values being assigned to the variable, decltype deduces the type from an expression passed to it.

What is the use of decltype?

The decltype type specifier yields the type of a specified expression. The decltype type specifier, together with the auto keyword, is useful primarily to developers who write template libraries. Use auto and decltype to declare a template function whose return type depends on the types of its template arguments.

What does decltype stand for?

Decltype keyword in C++ Decltype stands for declared type of an entity or the type of an expression. It lets you extract the type from the variable so decltype is sort of an operator that evaluates the type of passed expression. SYNTAX : decltype( expression )

Is decltype runtime or compile time?

decltype is a compile time evaluation (like sizeof ), and so can only use the static type.


1 Answers

(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.

like image 71
Lightness Races in Orbit Avatar answered Sep 21 '22 14:09

Lightness Races in Orbit