用于对类进行不同的局部专门化的Varadiac宏

Varadiac macros for making different partial specialization of a class

本文关键字:局部 专门化 Varadiac 用于      更新时间:2023-10-16

对于某些类,我们可以定义显式模板特化的宏,如下面的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预处理器文档来解决这个问题,但不能进行很多。是否有一个Boost预处理器解决方案?

这是一个使用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))