0

Suppose we had an istream subclass with the following method:

SomeStream& operator>>(Something& something) {
    // .. write data into something
}

And we also had the following global method:

Something& operator>>(istream& stream, Something& something) {
    // .. write data from stream into something
}

How does C++ know which method to call for the following code:

instanceOfSomeStream >> instanceOfSomething;

Follow up question: what is the better or more common way to allow a SomeStream to be written into a Something - should I add another overload for operator>> in SomeStream, that takes a Something& argument? Or should I go the opposite way, and create an overload in Something that takes a SomeStream? (Actually not in Something, but as a global function because of obvious reasons).

Aviv Cohn
  • 15,543
  • 25
  • 68
  • 131
  • Normally when you entend an `std::istream` or `std::ostream`, you do it for the purpose of wrapping a custom `std::streambuf`. If you need to provide I/O functionality for a type, do it by overloading the global `operator>>()`/`operator<<()` like in the second code block. Any custom behavior `SomeStream` may exhibit should be related to the buffer that it may use, otherwise it's not worth creating another stream type. – David G Oct 11 '14 at 01:56

1 Answers1

1

C++ has complicated overload resolution rules in general. In this case it's useful to know that a member function, for the purposes of overload resolution, behaves like a non-member function that takes a reference to the class as an implied first argument, i.e., the choice is between something like [1]

SomeStream& operator>>(SomeStream& somestream, Something& something)

and

Something& operator>>(istream& stream, Something& something)

Of course the return type doesn't matter, and for

instanceOfSomeStream >> instanceOfSomething

the first overload will be chosen because SomeStream is more derived than istream.

Your follow-up question should be a separate question. There's some discussion here which might be related: Should operator<< be implemented as a friend or as a member function?

[1] Note: I say "something like" because this is not exactly correct. For example such a member function can be called on an rvalue object expression even though an lvalue reference is shown above.

Community
  • 1
  • 1
Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • There are a number of differences between the implicit parameter and a reference you might declare yourself. And, the answer to the linked question is emphatically that it must be a free function. `istream` should never be subclassed except for something like `istringstream` of `ifstream`, i.e. to support a `streambuf` subclass. – Potatoswatter Oct 11 '14 at 03:14