如何专门化模板化运算符重载?

时间:2018-11-13 15:15:47

标签: c++ templates operator-overloading

我正在尝试将比较运算符重载为特定模板类sub的非成员,1)sub的实例之间,2)sub与特定变量之间,它返回第一种情况的comparer_sub实例,或者返回comparer_el的实例,它们对sub以及其他一些有用的成员进行比较:

template <typename T1, typename T2>
class sub_base {
public:
    sub_base() {};
};

template <typename T>
class mat {
    class sub : public sub_base<T,mat<T>> {
    public:
        sub(): sub_base<T,mat<T>>() {};
    };
public:
    int mb;
    sub getSub() {return sub();};
};

template <typename T1,typename T2>
class comparer_base {
public:
    comparer_base() {};
    void base_method() {};
};

template <typename lT1,typename lT2,typename rT1,typename rT2>
class comparer_sub :  public comparer_base<sub_base<lT1,lT2>,sub_base<rT1,rT2>> {
    using comparer_base<sub_base<lT1,lT2>,sub_base<rT1,rT2>>::base_method;
public:
    comparer_sub() : comparer_base<sub_base<lT1,lT2>,sub_base<rT1,rT2>>() {};
};

template <typename lT1,typename lT2,typename rT>
class comparer_el :  public comparer_base<sub_base<lT1,lT2>,rT> {
    using comparer_base<sub_base<lT1,lT2>,rT>::base_method;
public:
    comparer_el() : comparer_base<sub_base<lT1,lT2>,rT>() {};
};

template <typename lT1,typename lT2,typename rT1,typename rT2>
comparer_sub<lT1,lT2,rT1,rT2> operator== (const sub_base<lT1,lT2>& lhs, const sub_base<rT1,rT2>& rhs){
    printf("comparer_sub\n");
    return comparer_sub<lT1,lT2,rT1,rT2>();
};
template <typename lT1,typename lT2,typename rT>
comparer_el<lT1,lT2,rT> operator== (const sub_base<lT1,lT2>& lhs, const rT& rhs){
    printf("comparer_el\n");
    return comparer_el<lT1,lT2,rT>();
};

但是,我尝试执行第二次重载的任何类型的比较都被称为,我认为是由于const rt&太通用,并且sub的任何实例都适合该参数。

int main(int argc, char const *argv[])  {
    mat<int>     A;
    mat<float>  B;
    float C = 0.6;

    A.getSub() == B.getSub(); // comparer_el
    A.getSub() == C; // comparer_el

    return 0;
}

sub实例之间,如何强制将第一个重载的优先级设置为第二个重载的优先级?

1 个答案:

答案 0 :(得分:1)

问题在于,与从comparer_elrT=sub的替换+转换相比,subsub_base<rT1,rT2>的选择更好。推论不会隐式强制转换(除了放置其他c / v限定词之外)...有关更多说明,请阅读this answer

因此,一种解决方案不是在sub中使用返回类型getSub(),而是在基本类型sub_base<rT1,rT2>中使用返回类型。参见here

重要部分:

template <typename T>
class mat {
    class sub : public sub_base<T,mat<T>> {
    public:
        sub(): sub_base<T,mat<T>>() {};
    };
public:
    int mb;
    sub_base<T,mat<T>> getSub() {return sub();};
 // ^^^^^^^^^^^^^^^^^^ return type changed from sub to sub_base<T,mat<T>>
};