Overloaded ostream operator

Why can't the overloaded << operator be a member function of a class? I've looked around, but didn't find any clear answer. I've found that "operator << takes in an object of type ostream as first parameter, and therefore cannot be a class member function". But what differs this from other member functions of classes that takes various types as first argument?
You can overload the << operator be a member function of a class. BUT it can't then be used in the same way, syntactically, so it won't provide the same pattern that C++ people would be used to seeing (for stream operations).

When you do
cout << foo;
You are actually calling the operator<<([Type of cout], [Type of foo]).

But it can resolved to a member function as well:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Example program
#include <iostream>
#include <string>

class Foo {
  public:
    Foo()
    {
        
    }
    
    std::ostream& operator<<(std::ostream& os)
    {
        return os << 42;
    }
    
};

int main()
{
    using std::cout;
    
    Foo foo;
    foo << cout;
}


But this destroyed the pattern that we'd be used to seeing, where it's cout << foo, not foo << cout;

"a operator b" can match to be equivalent to operator(a, b) or a.operator(b).
(Note that this isn't always the case, for example the assignment operator has to be a member function.)

Edit:
But what differs this from other member functions of classes that takes various types as first argument?
Let me attempt to directly answer this. Other classes that take in various types as the "first" argument means that the "first" argument is the right-hand side of the binary operator. The actual left-hand side argument (the "real" first argument) is the object whose class we're defining the member function in.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// Example program
#include <iostream>
#include <string>

class Foo {
  public:
    Foo()
    {
        
    }
    
    int operator+(int b)
    {
        return 42 + b;
    }
    
    
    std::string operator+(std::string b)
    {
        return "42" + b;
    }
    
};

int main()
{
    using std::cout;
    
    Foo foo;
    cout << (foo + 12345); // Foo is LHS, int is RHS
    cout << (foo + "quack"); // Foo is LHS, string is RHS
    
    // Won't compile:
    (12345 + foo);
    ("quack" + foo);
}
Last edited on
Topic archived. No new replies allowed.