Reputation: 160
I was trying to write some operator overload functions, especially the <<
operator to use it with a custom class and an std::ofstream
object, but I was a bit confused by the syntax used in various examples found online. For example, let's consider the operator<<
overload as a non-member function for a simple custom class:
#include <fstream>
class Example {
public:
int first;
int second;
};
// I found this kind of operator on the Internet
std::ofstream& operator<< (std::ofstream& out, Example obj) {
out << obj.first << endl << obj.second;
return out;
}
int main() {
Example a={1,2};
std::ofstream out;
out.open("test");
out << a;
out.close();
}
I don't really get why It should return std::ofstream&
to work properly. I tried using the following operator
void operator<< (std::ofstream& out, Example obj) {
out << obj.first << endl << obj.second << endl;
}
and it worked as well. I mean, can't out << obj;
be interpreted as operator<< (out , obj);
? Why does it have to return something since I'm passing a reference to the std::ofstream
object?
The same doubt arose when I was trying to write an operator=
overload as a member function for a custom class, as the simple example that follows
class Custom{
public:
int up;
int down;
Custom& operator= (Custom a) {
up=a.up;
down=a.down;
return *this;
}
};
I used the copy-swap idiom for the assignment operator, so don't mind the operator definition too much, it's just an example. Again, writing
Custom obj1, obj2;
obj1 = obj2;
since I can interpret obj1 = obj2;
as obj1.operator=(obj2)
, why is the return type Custom&
required instead of void
?
Upvotes: 1
Views: 96
Reputation: 19607
If you want to be able to chain operator<<
s together, you have to use a return type (better std::ostream&
than std::ofstream&
, so you can use it for std::cout
and like, too).
out << a << b;
(out << a) << b;
^^^^^^^^^^
lhs has to be a stream
For assignment operator, the reason is essentially the same. C++ syntax allows you to write many expressions requiring the return type, for example this:
Custom obj1, obj2, obj3;
(obj1 = obj2) + obj3 ... // assign obj2 to obj1 and work with that...
Upvotes: 2
Reputation: 1172
You can write somthing like cout << "First operand" << "Second operand"
because first operand returns reference to ostream
and second operand works with this reference.
operator=
works same way. You can write a = b = c
, but also you can put it inside if (a = b)
or while (a = b)
. This can make your code shorter, but is a little dangerous.
Upvotes: 1
Reputation: 172924
Return a reference instead of void
, make it possible to write like
out << obj1 << obj2 << obj3;
For operator=
, you can write
obj1=obj2=obj3;
Upvotes: 1
Reputation: 92261
Returning a reference allows you to chain the operators, like
std::cout << e1 << e2;
Upvotes: 1