Как специализировать шаблонные перегрузки операторов? - PullRequest
0 голосов
/ 13 ноября 2018

Я пытаюсь перегрузить операторы сравнения как не являющиеся членами для определенного шаблонного класса 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 голосов
/ 13 ноября 2018

Проблема в том, что comparer_el с rT=sub - лучший выбор, чем подстановка + приведение от sub до sub_base<rT1,rT2>. Дедукция не подразумевает неявное приведение (кроме добавления дополнительных квалификаторов c / v) ... Для более лучшего описания прочитайте этот ответ .

Итак, одним из решений является не использование возвращаемого типа sub внутри getSub(), а базового типа sub_base<rT1,rT2>. см здесь

важная часть:

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>>
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...