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