我对元编程很陌生,我正在尝试一些例子。
我设计了一个可变模板类如下:
template <typename TA, typename... TB>
class A
[...]
这可以简单地通过传递不同类型(如(来实例化
A<Class1, Class2, Class3> * a = &(A<Class1, Class2, Class3>::instance());
其中包TB仅包含CCD_ 1和CCD_。现在,我想实现的是在头文件中定义一个默认类型列表,并使用#ifdef
定义逐步构建它。我会做一个的例子
// concept of list of types
template<class... Ts>
struct typelist{};
// concatenating two typelists
template<class... Ts, class... Us>
auto concat(typelist<Ts...>, typelist<Us...>) -> typelist<Ts..., Us...>;
static typelist<> defaultTypelist;
#ifdef MACRO1
defaultTypelist = concat(defaultTypelist, typelist<Class2>);
// or something like defaultTypelist.push_front(Class2);
#endif
#ifdef MACRO2
defaultTypelist = concat(defaultTypelist, typelist<Class3>);
// or something like defaultTypelist.push_front(Class3);
#endif
通过这样做,我主要想实例化我的对象如下:
A<Class1, defaultTypelist> * a = &(A<Class1, defaultTypelist>::instance());
我在这里看到的主要问题是,我无法逐渐将类型附加到defaultTypelist
,因为它是在空模板typelist<>
的开头声明的。如果我试图传递一个空的类型列表作为第二个参数,编译器也会返回一个错误。这可能很琐碎,但到目前为止我还没能解决这个问题,主要是因为,作为元编程的初学者,编译器错误对我没有太大帮助
对于这个项目,我必须使用C++14及以下版本。
肥胖警告:不要这样做。
我说的原因是,它会在代码期间发生变化。随着您逐渐添加类型,defaultTypeList
在代码的不同位置将具有多种含义。
也就是说。。。能做到吗?当然,
#define DEFAULT_TYPE_LIST typelist<>()
// ...
#ifdef MACRO1
static constexpr auto macro1_prev_dtl = DEFAULT_TYPE_LIST;
#undef DEFAULT_TYPE_LIST
#define DEFAULT_TYPE_LIST concat(macro1_prev_dtl, typelist<Class2>())
#endif
// ...
#ifdef MACRO2
static constexpr auto macro2_prev_dtl = DEFAULT_TYPE_LIST;
#undef DEFAULT_TYPE_LIST
#define DEFAULT_TYPE_LIST concat(macro2_prev_dtl, typelist<Class3>())
#endif
然后在您想访问列表的当前状态的任何位置使用DEFAULT_TYPE_LIST
。