The ostream class of C++ provides many default overloads for operator<<, however they are not all defined in the same way.
The overloads for char types, string types, and rvalue streams are defined as free namespace-scope functions such as:
namespace std {
ostream &operator<<(ostream &os, char c);
}
While the overloads for arithmetic types, streambuf, and stream manipulators are defined as member functions of std::ostream such as:
namespace std {
ostream &ostream::operator<<(int val);
}
My Question
Is there an reason for this distinction? I understand that calls to these operator overloads operate slightly differently (i.e. ADL for the free namespace-scope definitions), and so I'd imagine there might be a preference to a particular type of operator overload for optimization purposes. But here std::ostream uses both types of definitions for different types. Are there any advantages to this semantically or implementation optimizations that this allows for?