简体   繁体   English

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

[英]How to specialize templated operator overloads?

I'm trying to overload comparison operators as non-members for a particular templated class sub , 1) between instances of sub , and 2) between sub and a specific variable, which returns an instance of either comparer_sub for the first case and comparer_el in the alternative, which perform comparisons on sub along with some other useful members:我正在尝试将比较运算符重载为特定模板化类sub非成员,1) 在sub实例之间,以及 2) 在sub和特定变量之间,它返回一个comparer_sub的实例作为第一种情况和comparer_el in替代方法,它与其他一些有用的成员一起对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>();
};

However, any type of comparison I try to perform the second overload is called, what I assume is due to const rt& being too generic and any instance of sub fits that argument.但是,我尝试执行第二个重载的任何类型的比较都会被调用,我认为这是由于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;
}

How can I force the first overload to be prioritized over the second overload between instances of sub ??如何在sub实例之间强制第一个过载优先于第二个过载?

The problem is, comparer_el with rT=sub is a better choise than the substitution+cast from sub to sub_base<rT1,rT2> .问题是, comparer_elrT=sub比替代+铸造从更好的choise subsub_base<rT1,rT2> Deduction does not implicitly cast (except putting additional c/v qualifiers)... For a much better description, read this answer .演绎不会隐式转换(除了放置额外的 c/v 限定符)......要获得更好的描述,请阅读此答案

So, one solution is not to use return type sub within getSub() but the base type sub_base<rT1,rT2> .因此,一种解决方案不是在getSub()使用返回类型sub ,而是使用基本类型sub_base<rT1,rT2> see here这里

important part:重要部分:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM