如果需要,插入typename的C ++宏

时间:2014-10-07 10:21:29

标签: c++ templates macros typename

我有一个宏用于自动子类型化模板,继承构造函数如下所示:

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

请不要争论这样的宏是必要的还是好的风格。这对我们的项目很有帮助;我们用它来缩短很长模板的类型名称。例如,我们可以使用LongName<int,float,x::y::LongInnerType>缩短模板INST_TMPL(MyType,LongName,int,float,x::y::LongInnerType)的名称。现在我们可以简单地使用MyType而不是长模板,并且类型也将显示在错误消息中(而不是扩展的模板名称)。

但现在有一个问题:根据使用的模板,我们有时需要在宏内的typename中使用typedef。例如,如果使用的模板是模板参数T的内部模板,例如T::LongName<...>,那么我们需要typedef中的typename,即:

   typedef typename TMPL<__VA_ARGS__> Base;\

当然,我可以创建两个宏,一个带有typename而另一个没有。但是,这非常麻烦。相反,我想有一个宏,总是正确编译两种情况。这可能吗?

1 个答案:

答案 0 :(得分:3)

来自评论:

重写此方法的方法是通过宏参数指定typename,使用辅助模板类来简单地报告自己的模板参数。

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; \
  };

INST_IMPL(MyType,LongName<int,float,x::y::LongInnerType>)一样使用它,或者像INST_IMPL(MyType,typename T::LongName<int,float,x::y::LongInnerType>)一样使用。

即使这是非依赖类型,也允许使用typename id<...>::type