gexicide
gexicide

Reputation: 40068

C++ macro that inserts typename if necessary

I have a macro for auto-subtyping of a template with inheriting constructors which looks like this:

#define INST_TMPL(NAME,TMPL,...)  \
struct NAME : public TMPL<__VA_ARGS__> {    \
   typedef TMPL<__VA_ARGS__> Base;\
   using Base::Base;\ // Inherit constructors
};

Please no arguments whether such a macro is necessary or good style. It is very helpful in our project; we use it to shorten type names of very long templates. For example, we can shorten the name of a template LongName<int,float,x::y::LongInnerType> by using INST_TMPL(MyType,LongName,int,float,x::y::LongInnerType). Now we can simply use MyType instead of the long template and the type will also be displayed in error messages (instead of the expanded template name).

But now there is one Problem: Depending on the template used, we sometimes need a typename in the typedef inside the macro. For example, if the used template is an inner template of a template parameter T, e.g.T::LongName<...>, then we would need the typename in the typedef, i.e.:

   typedef typename TMPL<__VA_ARGS__> Base;\

Of course, I could create two macros, one with the typename and one without. However, that is quite cumbersome. Instead, I would like to have a macro that always compiles correctly for both scenarios. Is this possible?

Upvotes: 2

Views: 2103

Answers (1)

user743382
user743382

Reputation:

From the comments:

A way to rewrite this where typename can be specified through the macro arguments is to use a helper template class that simply reports its own template argument.

template <typename T>
struct id { typedef T type; };

#define INST_TMPL(NAME,...) \
  struct NAME : id<__VA_ARGS__>::type { \
    typedef typename id<__VA_ARGS__>::type Base; \
    using Base::Base; \
  };

Use it like INST_IMPL(MyType,LongName<int,float,x::y::LongInnerType>), or like INST_IMPL(MyType,typename T::LongName<int,float,x::y::LongInnerType>).

The use of typename id<...>::type is allowed even if this is a non-dependent type.

Upvotes: 3

Related Questions