If you really want to define an operator from the outside and make friends only with an instance of the operator that matches the type with that instance of the template, the correct syntax is:
template <typename T> class test; // forward declare template class template <typename T> // forward declare the templated operator std::ostream& operator<<( std::ostream&, test<T> const & ); template <typename T> class test { // define the template friend std::ostream& operator<< <T>( std::ostream&, test<T> const & ); // befriend }; template <typename T> // define the operator std::ostream& operator<<( std::ostream& o, test<T> const & ) { return o; }
In most cases, you should not pull the definition from the class, given that you still need to provide it in the header and additional work.
Also note that there are slight differences for the compiler regarding search. In the case when the function is built into the class definition, the compiler will not find this function unless one of the arguments is of the type of the template, therefore, it effectively reduces the visibility and the amount of work that the compiler should do, do (if the templated operator<< is defined outside class, the compiler will find it as a candidate for overload resolution in all places where it finds a << b , only to drop it in all cases when the second argument is not test<T> (and it will show the template operator as a candidate in all messages about mistake x, where it cannot match operator<< , which is already a long enough list).
source share