Search code examples
c++c++11c-preprocessordecltypetypename

Is "#define TYPE(x) typename decltype(x)" a bad idea?


Is it a bad idea to define

#define TYPE(x) typename decltype(x)

as a fast way to get the member type of the class of a variable in C++11?

Justification:

Consider the following (oversimplified) example:

#include <iostream>
#define TYPE(x) typename decltype(x)

class A {
public:
  typedef int mtype;
  void set(mtype const& x) { foo = x; }
  mtype get() { return foo; }
private:
  mtype foo;
};

A make() { return A(); }

int main() {
  auto a = make();
  TYPE(a)::mtype b = 3;
  a.set(b);
  std::cout << a.get() << "\n";
  return 0;
}

That is, I have a class with some member type "mtype" and a function which returns me an instance of this class. Thanks to auto, I don’t have to worry about the name of the class as long as I know that my function does its job. However, at one point or another, I have to define a variable of a specific type, which, for convenience, has a typedef to "mtype" in my class.

If I only have the variable name "a" around but I know that this variable has this class, I can do

typename decltype(a)::mtype b;

to define a variable b of type A::mtype.

Is it now a bad idea to put this "typename decltype" into a macro? Are there obvious, common cases in which it will break? Is there a better way to quickly get at this type?

Bonus: "a::mtype" would be nicest - is there a reason it is not defined to behave as "decltype(a)::mtype" in the standard?


Solution

  • Yes, this is bad. Use a template-using instead:

    template<class T>
    using mtype_t = typename T::mtype;
    

    Usage:

    auto a = make();
    mtype_t<decltype(a)> b = 3;