Im в настоящее время реализует крошечную библиотеку вычислений времени компиляции с метапрограммированием.Лучший способ (или обходной путь) для специализации псевдонима шаблона
Если вы определили базовый класс для операторов, у которых есть результат typedef (я решил использовать интегральные обертки, такие как std::integral_constant
как значения вместо необработанных интегральных значений, чтобы обеспечить единый интерфейс по библиотеке) и n- ичный оператор базового класса, который проверяет, если операторы имеет по крайней мере один из операндов:
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>;
этого оператор интерфейсы используются для определения пользовательских операторов, как псевдоним, li ke:
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;
};
Если оператор равенства был сделан uppon наследования, вместо наложения спектров, это можно легко сделать с помощью шаблона specialitation:
//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>> {};
Я знаю, что template alias cannot be specialized.
Мой вопрос: Есть ли способ, который не должен использовать наследование dessign вместо шаблонных псевдонимов, чтобы специализировать этот тип псевдонимов шаблонов?
У вас уже есть решение. Я не понимаю, что вы ищете (а именно, этот вопрос не объясняет, каковы недостатки существующего решения, которые нам нужно избегать, и каковы цели, которые не удается выполнить существующему решению, мы должны стремиться к). –
@ R.MartinhoFernandes Как я указал в вопросе, я знаю, что это можно сделать через наследование dessign вместо шаблонных псевдонимов. Вопрос только для любопытства. На самом деле путь наследования и способ псевдонимов похожи, но тот факт, что он не может быть сделан напрямую с помощью псевдонимов шаблонов, поражает меня. – Manu343726
@ Manu343726 вы ищете статическое наследование, и это, вероятно, можно сделать с помощью Curiously Recursive Template Pattern. http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern. – IdeaHat