5

I'm creating a Vector2 class in C++ as a template, and I want to define the + operator as a non-member friend function that can simply add two vectors.

This is the friend declaration inside my Vector2 template class:

template <class U>
friend Vector2<T> operator+(const Vector2<T> &lhs, const Vector2<T> &rhs);

This is contained in a .hpp file, but the implementation is in a separate .cpp file:

template <class T>
Vector2<T> operator+(const Vector2<T> &lhs, const Vector2<T> &rhs)
{
    return Vector2<T>(lhs.x_ + rhs.x_, lhs.y_ + rhs.y_);
}

This compiles without any warnings, however, it does not seem to work.

Vector2<int> v1(4, 3);
Vector2<int> v2(3, 4);

Vector2<int> v3 = v1 + v2;

When I try to compile the above snippet, GCC complains:

prog.cpp: In function ‘int main(int, char**)’:
prog.cpp:26:28: error: no match for ‘operator+’ in ‘v1 + v2’

source/vector2.hpp:31:23: note: template<class U> Vector2<int> operator+(const Vector2<int>&, const Vector2<int>&)
source/vector2.hpp:31:23: note:   template argument deduction/substitution failed:
prog.cpp:26:28: note:   couldn't deduce template parameter ‘U’
prog.cpp:26:18: warning: unused variable ‘v3’ [-Wunused-variable]

What am I doing wrong? How can I correctly define the + operator for my template class?

corazza
  • 31,222
  • 37
  • 115
  • 186
  • 7
    "This is contained in a .hpp file, but the implementation is in a separate .cpp file"... don't even try it. Put everything in a header. http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file – R. Martinho Fernandes Jan 14 '13 at 11:55
  • 2
    Look again at the template parameters in the `friend` declaration. There's a mismatch there. – Some programmer dude Jan 14 '13 at 11:57
  • T != U. maybe pick one =P – WhozCraig Jan 14 '13 at 11:59
  • I forgot to explain that, but I saw it in another SO answer, and basically I was asking why does it compile with different symbols (U, T), but not with the same ones (T, T). – corazza Jan 14 '13 at 12:41

2 Answers2

5

The compiler clearly states what the problem is. It cannot deduce the template parameter 'U'. Your declaration(the .hpp file) is wrong. Should be

template <class T>
friend Vector2<T> operator+(const Vector2<T> &lhs, const Vector2<T> &rhs);
BЈовић
  • 62,405
  • 41
  • 173
  • 273
Ventsyslav Raikov
  • 6,882
  • 1
  • 25
  • 28
  • source/vector2.hpp:30:15: error: declaration of ‘class T’ source/vector2.hpp:12:10: error: shadows template parm ‘class T’ – corazza Jan 16 '13 at 15:53
3

The template for the operator uses a parameter U that isn't used. The signature uses a T instead, that probably comes from a surrounding class template:

template <class U>
friend Vector2<T> operator+(const Vector2<T> &lhs, const Vector2<T> &rhs);

Because U isn't used, the compiler can't automatically deduce what type it should be and gives an error.

Use the template parameter consistently, put the definitions of any templates in the .hpp file, and you should be fine.

sth
  • 222,467
  • 53
  • 283
  • 367