在#define中使用模板参数类型

时间:2015-03-10 14:41:48

标签: c++ templates c-preprocessor

我的情况的背景很难在这里详尽解释,但是:我正在使用外部工具集(lib,bin等),它从专有的IDL文件生成一些c ++代码。对于给定类型T,它会生成T_Result类。然后将生成的代码集成到我的项目中。

现在,我正在尝试根据模板参数的类型生成一个类型。

#define GENTYPE(x) x ## _Result

// class coming from generated includes. Copied here for clarity.
class int_Result
{};

template < class T >
class Connector
{
    GENTYPE(T) _result;
public:

};

int main()
{
    Connector<int> t;
    /* ... */
}

当然,这不起作用,因为c预处理器使用T值,因此GENTYPE宏在Connector类中扩展为T_Result而不是想要的int_Result上课。

可以使用#define来生成整个类,但是很难维护,调试等。

有谁知道实现这一目标的诀窍?

1 个答案:

答案 0 :(得分:4)

我们使用宏来生成将Connector映射到T的特征类,而不是生成T_result的宏。然后Connector只使用该特征类。

template<class T>struct result_type;

#define MRT(T) \
  template<>struct result_type<T>{ \
    using type = GENTYPE(T); \
  }

template<class T>using result_t=typename result_type<T>::type;

现在只需执行MRT(int);即可result_t<int>int_result。必须在首次使用result_t<int>之前使用宏。如果MRT(int)失败,则result_t<int>会出错。

这假定C ++ 11支持:它是2015年。

Connector只需执行result_t<T> _result;

使用MRT是可选的,作为海峡

template<>struct result_type<int>{ using type=GENTYPE(int); };

甚至

template<>struct result_type<int>{ using type=int_result; };

并非所有详细信息,并且减少了宏的层数。但它确实违反了DRY(不要自己重复)。