Макросы Varadiac для создания различной частичной специализации класса

Для некоторых классов мы можем определить макросы, которые выполняют явную специализацию шаблона в качестве следующего примера из библиотеки Boost Serialization:

#define BOOST_IS_BITWISE_SERIALIZABLE(T)              \
namespace boost {                                     \
namespace serialization {                             \
template<>                                            \
struct is_bitwise_serializable< T > : mpl::true_ {};  \
}}                                                    \
/**/

Это работает для полной специализации, как BOOST_IS_BITWISE_SERIALIZABLE(MyClass<int>)

Но я хотел бы создать удобный макрос, который работает для частичной специализации с различными аргументами, как следующие:

template<class T, class Enable>
struct is_bitwise_serializable< MyClassA<T, Enable> > : mpl::true_ {};

template<class T>
struct is_bitwise_serializable< MyClassB<T> > : mpl::true_ {};

template<int N>
struct is_bitwise_serializable< MyClassC<N> > : mpl::true_ {};

.....

Я пытался просмотреть документацию Boost PreProcessor для этой проблемы, но не смог продолжить. Есть ли для этого решение Boost PreProcessor?

1

Решение

Вот решение, которое использует Boost.Preprocessor. Он построен на работе с последовательности.

#include <boost/mpl/bool.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/preprocessor/seq/transform.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>#define PARAM_NAME param

#define PARAM(Index) BOOST_PP_CAT(PARAM_NAME, Index)

#define PARAM_DESCRIPTION(Index, Data, ParamType) \
ParamType PARAM(BOOST_PP_SUB(Index, 2))

#define IS_BITWISE_SERIALIZABLE(TemplateClass, Params) \
template \
< \
BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(PARAM_DESCRIPTION,, Params)) \
> \
struct is_bitwise_serializable \
< \
TemplateClass \
< \
BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(Params), PARAM_NAME) \
> \
> \
: boost::mpl::true_ {};

Пример использования:

template <class T, class Enable>
struct MyClassA{};

template <class T>
struct MyClassB{};

template <int N>
struct MyClassC{};

template <class T, template <class> class Base = MyClassB>
struct MyClassD : public Base<T>{};IS_BITWISE_SERIALIZABLE(MyClassA, (class)(class))

IS_BITWISE_SERIALIZABLE(MyClassB, (class))

IS_BITWISE_SERIALIZABLE(MyClassC, (int))

IS_BITWISE_SERIALIZABLE(MyClassD, (class)(template <class> class))

Увидеть живой пример.

2

Другие решения


По вопросам рекламы [email protected]