Misunderstanding about ostream class and operator <<

末鹿安然 提交于 2019-11-29 13:43:31

The first group of operators are members of the stream class.

Most operator overloads, like those in the second group, are not.


As to the why, it is likely just a historical accident. The operators for built in types can be added to the stream classes, and obviously they were (long before C++ was standardized). The standard just documents existing practice here.

Operators for user defined types obviously cannot be added to the stream classes, so they are implemented as free functions.

In retrospect it would have been more consistent to make all the operators free functions, but that would possibly break some old programs.

The others have described the differences, here's my shot at why they are split.

The non-member versions, which take char variants as parameters are specialized depending on type of the target stream's base character type and handled depending on locale, because standard defines specific behavior (o << '1' has different behavior than oo << 33, it has to be handled properly if o is basic_ostream<wchar_t>, etc).

E.g. char writen to basic_ostream<wchar_t> is widened, while if written to basic_ostream<char> it is not (27.6.2.5.4). So actually there are multiple overloads of operator<<, e.g:

basic_ostream<_Elem, _Traits>& operator<<(basic_ostream<_Elem, _Traits>& _Ostr, char _Ch)
basic_ostream<char, _Traits>& <<(basic_ostream<char, _Traits>& _Ostr, char _Ch)

If they were defined as member functions, you wouldn't be able to specialize them like that as you would have to partially specialize the whole class, not just a single member, since standard doesn't allow partial specialization of member functions.

There are actually two families of overloader operator<<s, as you have found out.

One family is the overloaded member ostream::operator<< (which gets the ostream reference implicitly as the this pointer) and the other family is the overloaded free function operator<< which gets the ostream reference explicitly as an argument.

When you want to add streaming capability to a class of your own, you add a free function.

The reason for operator<< taking char is not a member function is that there already are functions defined in ostream which write characters to the stream.

basic_ostream& put(Ch c);
basic_ostream& write(const Ch* p, streamsize n);

Consequently these operators are made non-member functions which internally uses these two functions.

The first series are member functions, which return *this so operator chaining works.

The second series are freestanding functions (which as you say you can add for any class so you can stream them to a std::ostream), which have no this to return and return os instead to make operator chaining work.

Note that both work the same way at a call site.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!