必要时插入类型名的 C++ 宏

标签 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而不是长模板,并且类型也将显示在错误消息中(而不是扩展的模板名称)。

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

   typedef typename TMPL<__VA_ARGS__> Base;\

当然,我可以创建两个宏,其中一个带有 typename和一个没有。然而,这相当麻烦。相反,我希望有一个对于这两种情况都能正确编译的宏。这可能吗?

最佳答案

来自评论:

一种重写此方法的方法,其中 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即使这是非依赖类型也是允许的。

关于必要时插入类型名的 C++ 宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26233807/

相关文章:

c++ - 为什么派生类不能代替基类作为模板参数?

gcc - 错误 : junk `bswapl eax movl %eax' after register

c - GNU cpp 是否奇怪地为零参数的宏解释 C99 标准?

c++ - 使用 C++ 从 bios 获取 Assets 标签和序列号

c++ - 有没有办法使用特征使 pos_type 和 off_type 成为 int64_t?

c++ - 给定一个二维字符矩阵,我们必须检查给定的单词是否存在于其中

c++ - 内联函数

c++ - 将二维数组的 1 维复制到同一数组的另一部分

c++ - for_each 算法循环 boost::multi_array

c++ - 在头文件中使用私有(private)命名空间中的声明