But you can overload the operator<< for an fstream that returns a reference to an fstream and it should work.
Or a reference to an ofstream if you're using one of those... either way, chaining is problematic. See the code below (modified to use a string stream rather than a file stream to simplify things:)
I tried your code and it runs fine... There must be something wrong with my code, and it's strange because its structured the same way...
Now I have another question concerning overload. I wrote this code and it didn't compile:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
fstream & operator << (fstream&fs, lib& l)
{
fs << '{';
for (Book b : l.booklist)
{
fs << 'B';
fs << b;
}
for (User u : l.userlist)
{
fs << 'U'<<u;
}
fs << '}';
return fs;
}
Notice the bold part. It gives me an error: "binary '<<': no operator found which takes a right-hand operand of type 'User' (or there is no acceptable conversion)"
Although I overloaded my user just fine. But if I split the output like this:
It compiles, runs, and gives the output defined in the User overload just fine.
Any idead why?
See the post directly above your last one. Chaining is problematic. The only time your overload will be used is if it is the first item in the chain (or follows the first x items which also use your overload in the chain.)
fs << 'U'<<u;
is equivalent to:
1 2
auto retVal = fs << 'U'; // where the retVal is a std::ostream&
retval << u; // so the ostream overload is called here.
I see.
Then why does the ostream overload persists through the whole stream and the derived classes overload does not? Is there a way to tell it not to?
Your overload persists, but you don't have an overload for fstream& operator>>(fstream&, char), which would be required for the code to work since you use the return value from that function call to feed the next in the chain of calls. As you can imagine, exhaustively defining all possible overloads isn't something you want to do. You can get around this with a little template magic, but then you're suddenly changing potential behavior for all interactions with different stream types which is a mess of its own.
Don't try to subvert the system to do something it was designed not to do. Streams are generic so that you can treat them all the same. Your point of customization should be supplied by the class itself as a member function or as a stand-alone function that returns a string that can be fed to your stream or possibly a wrapper type that will define the correct behavior.