0

I was trying to make overload operator+ in templated class "test", it works with the same types and with converter I was able to add class object and regular type(e.g. test + int). But, when I try to add two class objects with different types I get this message

error C2666: 'test::operator +': 2 overloads have similar conversions ...Templater.cpp(14,17): message : could be 'test test::operator +(test,test)' [found using argument-dependent lookup] ...Templater.cpp(14,17): message : or 'test test::operator +(test,test)' [found using argument-dependent lookup] ...Templater.cpp(25,18): message : while trying to match the argument list '(test, test)'

Here's the code:

#include <iostream>
using namespace std;

template <class T>
class test {
public:
    T first, second;
    test(T a = 0, T b = 0) : first(a), second(b) {};
    //converter
    template <typename X>
    operator test<X>() {
        return test<X>(first, second);
    }
    friend test operator+(test left, test right) {
        return test(left.first + right.first, left.second + right.second);
    }
    friend std::ostream& operator<<(std::ostream& Str, test c) {
        return (Str << c.first << " " << c.second);
    }
};

int main() {
    test<float> a(1.2, 5.4);
    test<int> b(4.7, 17.5);
    cout << a + b;
}

I was looking for an answer, but only found cases with same types

Filburt
  • 17,626
  • 12
  • 64
  • 115
  • since `test` and `test` are two different types, you have to declare the operator loading as a friend template, something like `template friend test operator+(test left, test right) {...}` – Nimrod Oct 12 '22 at 06:07
  • So what do you expect the type of `a + b` to be? `test` or `test` and why? – user17732522 Oct 12 '22 at 06:08

1 Answers1

0

In general, it is possible, but it will not work exactly as you expect. In your version of the operator+, you accept two SAME types (two templates with the same arguments). If you want to be able to add different types, you either have to write cast operators from one type to another, or have to create an operator that accepts different types. In any case, you should think carefully about what type you want to return.

Problem with your cast operator is described in another question. And here is what

Here I have given an example of a function that takes as input any 2 variants of the test template and returns a result of the type of the first argument. The only limitation is the ability to add template arguments types. And the only change from your option here is the addition of a template for the operator's second argument

#include <iostream>
using namespace std;

template <class T>
class test {
public:
    T first, second;
    test(T a = 0, T b = 0) : first(a), second(b) {};
    //converter
    template <typename X>
    operator test<X>() {
        return test<X>(first, second);
    }
    template<class U>
    friend test operator+(test left, test<U> right) {
        return test(left.first + right.first, left.second + right.second);
    }
    friend std::ostream& operator<<(std::ostream& Str, test c) {
        return (Str << c.first << " " << c.second);
    }
};

int main() {
    test<float> a(1.2, 5.4);
    test<int> b(4.7, 17.5);
    cout << a + b;
}
Deumaudit
  • 978
  • 7
  • 17