Сценарии, в которых для вывода шаблона требуется неявное преобразование, определенное пользователем - PullRequest
0 голосов
/ 10 июня 2018

У меня есть шаблон класса, который включает перегруженный шаблон оператора и конструктор неявного преобразования, подобный следующему:

#include <utility>

template <class A, class B>
class X {
public:
    A a;
    B b;

    X(A a, B b) : a(a), b(b) {}
    X(std::pair<A, B> &value) : a(value.first), b(value.second) {}

    template <class C>
    friend X<A, C> operator+(const X<A, B> &left, const X<B, C> &right) {
        return X<A, C>(left.a, right.b);
    }
};

int main() {
    X<int, int> a(1, 2);
    X<int, float> b(1, 2.5f);
    std::pair<int, float> c(1, 2.5f);

    a + b; // Valid
    a + c; // Template deduction error
}

Я нашел этот ответ на другой вопрос, ноЯ не вижу способа реализовать это решение здесь.(Обратите внимание, что важно, чтобы второй параметр шаблона первого аргумента и первый параметр шаблона второго аргумента были одинаковыми, фактическая реализация оператора не так тривиальна, но интерфейс одинаков.

1 Ответ

0 голосов
/ 10 июня 2018

@ R-Sahu и ссылка , на которую вы ссылаетесь, уже ответили на ваш вопрос.Но решение было бы обеспечить другой оператор + для типов, которые не являются X, который выполняет преобразование после вычета для C,

#include <utility>

template <class A, class B>
class X {
public:
    A a;
    B b;

    X(A a, B b) : a(a), b(b) {}
    X(const std::pair<A, B> &value) : a(value.first), b(value.second) {}


    template <class C,template <typename, typename> typename O >
    friend X<A, C> operator+(const X<A, B> &left, const O<B, C> &right) {
       return left + X<B,C>(right);
    }
    template <class C>
    friend X<A, C> operator+(const X<A, B> &left, const X<B, C> &right) {
       return X<A, C>(left.a,right.b);
    }
};


int main() {
    X<int, int> a(1, 2);
    X<int, float> b(1, 2.5f);
    std::pair<int, float> c(1, 2.5f);

    a + b; // Valid
    a + c; // Works
}

Демо

...