私は現在、小さなメタプログラミング ベースのコンパイル時計算ライブラリを実装しています。
結果の typedef を持つ演算子の基本クラスを定義した場合 (std::integral_constant
ライブラリに沿って統一されたインターフェイスを提供するために、生の整数値の代わりに as 値のような積分ラッパーを使用することにしました)、および n-ary 演算子の基本クラスを定義した場合、演算子に少なくとも 1 つのオペランドがあるかどうかをチェックします。
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" );
};
そこで、単項演算子と二項演算子のエイリアスを次のように定義しました。
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>;
その演算子インターフェイスは、以下の比較演算子のように、カスタム演算子をエイリアスとして定義するために使用されます。
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>>;
ここで、独自のクラスにカスタムの等価演算子を実装するとします。例えば:
template<typename X , typename Y , typename Z>
struct vec3
{
using x = X;
using y = Y;
using z = Z;
};
等価演算子がエイリアシングではなく継承時に作成された場合、これはテンプレートの特殊化によって簡単に実行できます。
//Equality comparator implemented through inheritance:
template<typename LHS , typename RHS>
struct equal : public binary_operator<LHS,RHS,bool_wrapper<LHS::value == RHS::value>> {};
//Specialization 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>> {};
テンプレート エイリアスを特殊化できないことはわかっています。
私の質問は次のとおりです。テンプレート エイリアスの代わりに継承設計を使用せずに、この種のテンプレート エイリアスを特殊化する方法はありますか?