c – 专门化模板别名的最佳方式(或解决方法)
发布时间:2020-12-16 09:46:30 所属栏目:百科 来源:网络整理
导读:我目前正在实现一个基于元编程的微型编译时计算库. 如果为运算符定义了一个基类,那么它有一个结果typedef(我已经决定使用整数包装器,如std :: integral_constant作为值而不是原始整数值,以便在库中提供统一的接口),以及n-ary运算符基类,检查运算符是否至少有
我目前正在实现一个基于元编程的微型编译时计算库.
如果为运算符定义了一个基类,那么它有一个结果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" ); }; 所以我为一元和二元运算符定义了别名: 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,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,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; }; 如果相等运算符是继承的,而不是别名,则可以通过模板专门轻松完成: //Equaity comparator implemented through inheritance: template<typename LHS,typename RHS> struct equal : public binary_operator<LHS,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,Z2>,bool_wrapper<X1 == X2 && Y1 == Y2 && Z1 == Z2>> {}; 我知道template alias cannot be specialized. 解决方法
我用来专门化模板别名(或提供递归别名)的模式是拥有一个相应的_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>; 用户必须专注于my_alias_impl,但公共接口的其余部分仍然保持干净. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |