专门化模板别名的最佳方法(或解决方法) [英] Best way (Or workaround) to specialize a template alias

查看:147
本文介绍了专门化模板别名的最佳方法(或解决方法)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Im currently implementing a tiny metaprogramming-based compile-time computations library.

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

If have defined a base class for operators, wich has a result typedef (I have decided to use integral wrappers like std::integral_constant as values instead of raw integral values, to provide an uniform interface along the library), and a n-ary operator base class, that checks if the operators has at least one operand:

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" );
};

因此,我为一元和二进制运算符定义了别名:

So I defined alias for unary and binary operators:

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>;

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

That operator interfaces are used to define custom operators as alias, like comparison operators bellow:

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>>;

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

Now suppose we want to implement our custom equality operator for our own class. For example:

template<typename X , typename Y , typename Z>
struct vec3
{
    using x = X;
    using y = Y;
    using z = Z;
}; 

如果将相等运算符设为uppon继承,而不是使用别名,则可以通过模板专用化轻松完成此操作:

If the equality operator was made uppon inheritance, instead of aliasing, this could be easily done through template 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>> {}; 

我知道模板别名不能专门化.
我的问题是:有没有一种方法,不是使用继承设计代替模板别名来专门化这种模板别名?

I know that template alias cannot be specialized.
My quesion is: Is there a way, that is not to use inheritance dessign instead of template aliases, to specialize this kind of template aliases?

推荐答案

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

The pattern I use to specialize template aliases (or provide recursive aliases) is to have a corresponding _impl struct. For example:

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,但其余公共接口仍然保持清洁.

Users would have to specialize on my_alias_impl instead, but the rest of the public interface remains clean.

这篇关于专门化模板别名的最佳方法(或解决方法)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆