2

I'm sorry if this question has been answered allready but I have a read a lot of questions considering overloading this operator in a template class but I haven't found a particular case like mine.

This is my code:

#include <iostream>

using std::cout; 
using std::endl;
using std::ostream;

template <typename T>
class Class
{
    T x;
    public:
    friend ostream& operator << (const Class<T>&, ostream& out);
};

template <typename T>
ostream& operator << (const Class<T>&, ostream& out)
{
    return (out << out.x << endl);
}

int main()
{
    Class<short> object;
    cout << object << endl;
}

And I get this error on last line: Error 1 error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'Class' (or there is no acceptable conversion) g:\ucenje\objektno orijentirano programiranje\template3\template3\main.cpp 25 1 template3

Scarass
  • 914
  • 1
  • 12
  • 32
  • Possible duplicate of [friend declaration declares a non-template function](http://stackoverflow.com/questions/4039817/friend-declaration-declares-a-non-template-function) – 001 Jun 14 '16 at 10:21

2 Answers2

4

The arguments to the operator<< functions have been switched, it should be e.g

friend ostream& operator << (ostream& out, const Class<T>&1);

The left-hand side of all binary operators is always the first argument, and the right-hand side is the second argument.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
4

1.std::ostream should be the 1st parameter of operator<<, so

template <typename T>
ostream& operator << (const Class<T>&, ostream& out)

should be

template <typename T>
ostream& operator << (ostream& out, const Class<T>& c)

2.You defined operator<< as a template function, but friend ostream& operator << (const Class<T>&, ostream& out); points to a non-template function, you should change it to

friend ostream& operator<< <T>(ostream& out, const Class<T>& c);

And add some forward declarations before the declaration of the class:

template <typename T>
class Class;
template <typename T>
ostream& operator << (ostream& out, const Class<T>& c);

LIVE1

Or you can define operator<< as non-template function inside the definition of class.

template <typename T>
class Class
{
    T x;
    public:
    friend ostream& operator<< (ostream& out, const Class<T>& c)
    {
        out << c.x << endl;
        return out;
    }
};

LIVE2

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • @Scarass No. `operator<<` must be a non-member function. – songyuanyao Jun 14 '16 at 10:35
  • @Scarass No, it's true for non-template class too. Note `operator<<` must take `ostream` as its first argument, and you can think that the member function will always take the object as its 1st argument (as `this` pointer). – songyuanyao Jun 14 '16 at 10:40