C++: Operators and Templates

Following and example I took from another question, I understand why this does not work:

struct Foo {
    Foo() {}
    Foo(int) {}
    Foo operator+(Foo const & R) { return Foo(); }
};


struct Bar {
    Bar() {}
    Bar(int) {}
};

Bar operator+(Bar const & L, Bar const & R) {
    return Bar();
}


int main() {
    Foo f;
    f+1;  // Will work - the int converts to Foo
    1+f;  // Won't work - no matching operator
    Bar b;
    b+1;  // Will work - the int converts to Bar
    1+b;  // Will work, the int converts to a Bar for use in operator+

}

But then, if I change it to use templates in this way:

template <class T>
struct Foo {
    Foo() {}
    Foo(T) {}
    Foo operator+(Foo const & R) { return Foo(); }
};


template <class T>
struct Bar {
    Bar() {}
    Bar(T) {}
};

template <class T>
Bar operator+(Bar const & L, Bar const & R) {
    return Bar();
}


int main() {
    Foo<int> f;
    f+1;  // Will work - the int converts to Foo
    1+f;  // Won't work - no matching operator
    Bar<int> b;
    b+1;  // DOES NOT WORK
    1+b;  // DOES NOT WORK

}

It does not work. Can anyone put some light on this? Templates are driving me crazy.

Thanks.

Answers


There are two problems.

  1. You need to add the template type to the arguments in the definition of the operator. This is necessary because it needs to use them to know which instantiation of Bar to use.
  2. If you want mixed operators (that operate on two separate types) in a template function, you're going to need to provide the definitions for all of the mixed cases. Otherwise, the template deduction system won't work the way you want.

.

template <class T>
Bar<T> operator+(Bar<T> const & L, Bar<T> const & R) { // Fixed
    return Bar<T>();
}

template <class T>
Bar<T> operator+(Bar<T> const & L, const T & R) { // Added
    return L + Bar<T>(R);
}


template <class T>
Bar<T> operator+(const T& L, Bar<T> const & R) { // Added
    return Bar<T>(L) + R;
}

There's no implicit conversion between int and Bar, only between int and Bar<int>. In fact, you haven't defined a type Bar; instead, you have a family of types Bar<T> for various values of T. Probably you're seeing a compiler error connected to the definition of operator+, though it's likely hidden behind a thicket of other templated-type errors.

I don't have a c++ compiler in front of me, but I believe template<class T> Bar<T> operator+(Bar<T> const & L, Bar<T> const & R) will behave as you expect.


Need Your Help

Find in List<t> and return boolean if found

c# linq

please excuse my ignorance am somewhat of a novice (but enthusiastically getting there)

Strange Lint-errors in Android project

android android-lint

since I updated my Android SDK today I get some strange Lint errors in my project. The activity contains amongst others a textview. Everything works fine, but if I want to change the text size of the