5
votes

I'm currently using macros to declare relatively long lists of partially specialized template classes with better brevity. Somewhat oversimplified examples follow:

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

This works fine if I have no commas to pass in with each case:

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

And it has a tolerable workaround if I have a comma to pass through a single level of macro expansion:

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

But it fails if I try to add an additional layer of macros:

#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);

Trying to add an extra macro indirection level (via #define MacroComma2 MacroComma or various other attempts) keeps failing. Extra parentheses don't work when the substitution is going inside a template argument list. There seems to be a trick with variadic macros which might work, but I'm trying to keep C++2003 standard compliant. Is it possible to multiply "escape" a comma within a macro in some way in C++2003?

Alternatively, is there a terse way to declare long lists of partial specializations without using macros at all? My Google-fu hasn't found anything relevant, but it seems like there ought to be some sort of typelist metaprogramming trick.

1
Just don't use macros for this. Its not what they are designed for and abusing them just makes it harder for the maintainer. Don't be lazy spell it out.Martin York
do you have a long list of templates or template parameters?Anycorn

1 Answers

3
votes

one of many solutions using 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));

further read: http://www.boostpro.com/mplbook/preprocessor.html