Q:

What does this code do and why does it compile?

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?

A:

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);

A:

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.

