最好的方法(或解决方法)专门化模板别名

Man*_*726 4 c++ template-specialization template-meta-programming c++11 template-aliases

我目前正在实现一个基于元编程的微型编译时计算库.

如果已经为运算符定义了一个基类,那么它有一个结果typedef(我已经决定使用整数包装器,如std::integral_constant值而不是原始整数值,以便在库中提供统一的接口),以及一个n-ary运算符基类,检查运算符是否至少有一个操作数:

template<typename RESULT>
struct operator
{
    using result = RESULT;
};

template<typename RESULT , typename... OPERANDS>
struct nary_operator : public operator<RESULT>
{
    static_assert( sizeof... OPERANDS > 0 , "An operator must take at least one operand" );
};
Run Code Online (Sandbox Code Playgroud)

所以我为一元和二元运算符定义了别名:

template<typename OP , typename RESULT>
using unary_operator = nary_operator<RESULT , OP>;

template<typename LHS , typename RHS , typename RESULT>
using binary_operator = nary_operator<RESULT , LHS , RHS>;
Run Code Online (Sandbox Code Playgroud)

该操作符接口用于将自定义运算符定义为别名,如下面的比较运算符:

template<typename LHS , typename RHS>
using equal = binary_operator<LHS,RHS,bool_wrapper<LHS::value == RHS::value>>;

template<typename LHS , typename RHS>
using not_equal = logical_not<equal<LHS,RHS>>;

template<typename LHS , typename RHS>
using less_than = binary_operator<LHS,RHS,bool_wrapper<LHS::value < RHS::value>>;

template<typename LHS , typename RHS>
using bigger_than = less_than<RHS,LHS>;

template<typename LHS , typename RHS>
using less_or_equal = logical_not<bigger_than<LHS,RHS>>;

template<typename LHS , typename RHS>
using bigger_or_equal = logical_not<less_than<LHS,RHS>>;
Run Code Online (Sandbox Code Playgroud)

现在假设我们想为我们自己的类实现我们的自定义相等运算符.例如:

template<typename X , typename Y , typename Z>
struct vec3
{
    using x = X;
    using y = Y;
    using z = Z;
}; 
Run Code Online (Sandbox Code Playgroud)

如果相等运算符是继承的,而不是别名,则可以通过模板专门轻松完成:

//Equaity comparator implemented through inheritance:
template<typename LHS , typename RHS>
struct equal : public binary_operator<LHS,RHS,bool_wrapper<LHS::value == RHS::value>> {};

//Specialitation of the operator for vec3:

template<typename X1 , typename Y1 , typename Z1 , typename X2 , typename Y2 , typename Z2>
struct equal<vec3<X1,Y1,Z1>,vec3<X2,Y2,Z2>> : public binary_operator<vec3<X1,Y1,Z1>,vec3<X2,Y2,Z2> , bool_wrapper<X1 == X2 && Y1 == Y2 && Z1 == Z2>> {}; 
Run Code Online (Sandbox Code Playgroud)

我知道模板别名不能专门化.
我的问题是:是否有一种方法,即不使用继承dessign而不是模板别名来专门化这种模板别名?

bst*_*our 5

我用来专门化模板别名(或提供递归别名)的模式是拥有一个相应的_impl结构.例如:

template <typename T>
struct my_alias_impl { /* def'n */ };

template <>
struct my_alias_impl<int> { /* alternate def'n */ };

template <typename T>
using my_alias = my_alias_impl<T>;
Run Code Online (Sandbox Code Playgroud)

用户必须专注于my_alias_impl,但公共接口的其余部分仍然保持干净.