C++ – Why doesn’t this << overload compile

c++operator-overloading

I can't figure out why the following code doesn't compile. The syntax is the same as my other operator overloads. Is there a restriction that the << overload must be friended? If so, why? Thanks for any help.

This doesn't work –

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>

class Test
{
 public:
explicit Test(int var):
    m_Var(var)
    {   }

    std::ostream& operator<< (std::ostream& stream)
    {
        return stream << m_Var;
    }
 private:
int m_Var;

 };

 int _tmain(int argc, _TCHAR* argv[])
 {
Test temp(5);

std::cout << temp;

return 0;
}

This does work –

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>

class Test
{
public:
explicit Test(int var):
    m_Var(var)
    {   }

    friend std::ostream& operator<< (std::ostream& stream, Test& temp);

private:
    int m_Var;

 };

 std::ostream& operator<< (std::ostream& stream, Test& temp)
 {
return stream << temp.m_Var;
 };

 int _tmain(int argc, _TCHAR* argv[])
 {
Test temp(5);

std::cout << temp;

return 0;
 }

Best Solution

Here's the fundamental reason why the stream operators have to be friends.

Take this code:

   struct Gizmo
    {
        ostream& operator<<(ostream& os) const
        {
            os << 42;
        }
    };


    int main()
    {
        Gizmo g;
        cout << g;
        return 0;
    }

Consider the context of the call to cout << g; When the compiler compiles this function, it first tries this:

cout.operator<<(g);

...and if that isn't found, then it looks in the global namespace for:

operator<<(cout, g);

...and if that isn't found, then it can't be compiled.

But when you try to implement the stream insertion operator as a member of Gizmo, you are hoping the compiler will resolve your code to:

g.operator<<(cout);

...which it can't do unless you change your code to:

g << cout;

...which is obviously not what you're going for.