通过宏安全地传递模板参数逗号?

时间:2011-12-28 22:22:25

标签: c++ templates macros

我目前正在使用宏来声明具有更好简洁性的相对较长的部分专用模板类列表。有些过于简单的例子如下:

#define INSTANTIATE_MYTYPE(freeargs, specialization, myvalue) \
template <freeargs> \
struct MyType <specialization> {
  static const bool value = myvalue;
}

如果我没有逗号来传递每种情况,这样可以正常工作:

INSTANTIATE_MYTYPE(typename T, std::vector<T>, true);

如果我有一个逗号可以通过单一级别的宏扩展,它有一个可容忍的解决方法:

#define MacroComma ,
INSTANTIATE_MYTYPE(typename S MacroComma typename T,
                   std::pair<S MacroComma T>, true);

但如果我尝试添加额外的宏层,它就会失败:

#define INSTANTIATE_ALL(freeargs, specialization, myvalue) \
INSTANTIATE_MYTYPE(freeargs, specialization, myvalue); \
INSTANTIATE_ANOTHERTYPE(freeargs, specialization, myvalue); \
INSTANTIATE_ATHIRDTYPE(freeargs, specialization, myvalue)
// etcetera

INSTANTIATE_ALL(typename S MacroComma typename T,
                std::pair<S MacroComma T>, true);

尝试添加额外的宏间接级别(通过#define MacroComma2 MacroComma或其他各种尝试)会一直失败。当替换进入模板参数列表时,额外的括号不起作用。似乎有一个可变的宏可能有用的技巧,但我试图保持C ++ 2003标准兼容。是否有可能在C ++ 2003中以某种方式在一个宏中“转义”逗号?

或者,是否有简洁的方法来声明部分特化的长列表而根本不使用宏?我的Google-fu没有发现任何相关内容,但似乎应该有某种类型列表元编程技巧。

1 个答案:

答案 0 :(得分:3)

使用boost pp的许多解决方案之一

#define INSTANTIATE_MYTYPE(DATA)                          \
template <BOOST_PP_SEQ_ELEM(0,DATA)>                      \
struct MyType <BOOST_PP_SEQ_ELEM(1,DATA)> {               \
    static const bool value = BOOST_PP_SEQ_ELEM(2,DATA);  \
}

INSTANTIATE_MYTYPE((typename T, ...)
                   (std::vector<T>, ....)
                   (true));

进一步阅读:http://www.boostpro.com/mplbook/preprocessor.html