Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #5152 > unrolled thread
| Started by | "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> |
|---|---|
| First post | 2011-05-19 01:39 +0200 |
| Last post | 2011-05-19 18:11 -0400 |
| Articles | 3 — 3 participants |
Back to article view | Back to comp.lang.c++
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: ::std::ostream << char "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> - 2011-05-19 01:39 +0200
Re: ::std::ostream << char Björn <hen03@nurfuerspam.de> - 2011-05-19 23:27 +0200
Re: ::std::ostream << char Pete Becker <pete@versatilecoding.com> - 2011-05-19 18:11 -0400
| From | "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> |
|---|---|
| Date | 2011-05-19 01:39 +0200 |
| Subject | Re: ::std::ostream << char |
| Message-ID | <ir1l04$h6k$1@dont-email.me> |
* Stefan Ram, on 19.05.2011 00:54:
> The output operator "<<" for operands of type »::std::ostream« and »char« (in
> this order) seems to be defined as a non-member, while for »double« it seems
> to be defined as a member.
This may depend on which standard you're talking about. I haven't checked but as
I recall some of the issues related to this were fixed in C++0x. Which is on its
way Real Soon Now.
> Why is this so?
Historical accident.
> Bjarne Stroustrup already explained some of this: He said that "<<" /can/ be
> defined as a non-member, because the class already has the member »put«, so
> it can be defined outside of the class using »put«. But why do we /prefer/
> this?
We don't. Perhaps some do. It depends on what functionality you desire:
* Member (of LHS type), can be called on temporary.
* Non-member (of LHS type), can be invoked on object that just provides
conversion to the relevant formal argument type.
To me, the possibility of calling << with a left hand side operand that just
provides a conversion to referece to the relevant stream type, is completely
irrelevant.
> Herb Sutter explained, why "<<" for his class »Complex« has to be defined as
> a non-member of this class »Complex«, but his reason does not apply to the
> class »::std::ostream« as far as I understand it.
Now you're talking about the right hand side operand type.
That's a different thing.
An expression like "a << b" makes sense as "a.operator<<( b )" if the operator
is a member of typeof(a), but not if it is a member of typeof(b).
> Sometimes people say: When you define the operators as non-members and the
> class has implicit conversion operators, those implicit conversions will
> behave more symmetric with respect to the two operands of a binary operator,
> when this operator is defined as a non-member. I can not understand all of
> this, because I lack some prerequisites, but I have a vague idea of what it
> might mean. Does this reason apply to »::std::ostream« and "<<
> static_cast<char>(...)"?
In practice such conversions do not intrude very much.
However, when you define a symmetric operator like +, then it doesn't make much
sense to single out the left hand argument as special.
So then it might feel much more natural to define a non-member function.
> Could someone give a specific example of a case where something would be
> worse when "<< static_cast<char>(...)" would have been defined as a member
> of ::std::ostream?
Define "worse".
> Or, an example of a case where something would be worse when "<<
> static_cast<double>(...)" would have been defined as a non-member of
> ::std::ostream?
>
> (This question is inspired by a similar question posted into the German
> language C++ newsgroup by someone else recently.)
Oh, them Germans.
Cheers & hth.,
- Alf
--
blog at <url: http://alfps.wordpress.com>
[toc] | [next] | [standalone]
| From | Björn <hen03@nurfuerspam.de> |
|---|---|
| Date | 2011-05-19 23:27 +0200 |
| Message-ID | <ir420o$6kt$1@online.de> |
| In reply to | #5152 |
Alf P. Steinbach /Usenet wrote: > * Stefan Ram, on 19.05.2011 00:54: >> The output operator "<<" for operands of type »::std::ostream« and >> »char« (in this order) seems to be defined as a non-member, while >> for »double« it seems to be defined as a member. > > This may depend on which standard you're talking about. I haven't > checked but as I recall some of the issues related to this were > fixed in C++0x. Which is on its way Real Soon Now. In the current draft N3242 from 2011-02-28 it is still as described. >> Bjarne Stroustrup already explained some of this: He said that "<<" >> /can/ be defined as a non-member, because the class already has the >> member »put«, so it can be defined outside of the class using >> »put«. But why do we /prefer/ this? > > We don't. Perhaps some do. It depends on what functionality you > desire: > > * Member (of LHS type), can be called on temporary. > > * Non-member (of LHS type), can be invoked on object that just > provides > conversion to the relevant formal argument type. > > To me, the possibility of calling << with a left hand side operand > that just provides a conversion to referece to the relevant stream > type, is completely irrelevant. I agree. I cannot imagine any reason to define an output stream class which is not derived from std::basic_ostream but on the other hand every library and particularly the STL should be as flexible as possible. I found at least a reason why some operator<< are members of std::basic_ostream. They all have operands which will be converted to several characters usually (numbers, pointers, and another stream buffer). So, for an implementation it will probably be more efficient if they insert the produced characters directly into the output buffer -- if available -- than passing a temporary buffer to std::basic_ostream::write. The remaining operator<< in <ostream> only insert single characters. Another operator<< is in <string> to insert std::basic_string. But in case of a string you have to copy a character sequence into the output buffer, anyway, so it doesn't hurt that it's not a member function. I haven't checked if there are more operator<< in the STL. > However, when you define a symmetric operator like +, then it > doesn't make much sense to single out the left hand argument as > special. > > So then it might feel much more natural to define a non-member > function. For me it feels more natural to define everything inside according to the rule "as local as possible". >> (This question is inspired by a similar question posted into the >> German language C++ newsgroup by someone else recently.) > > Oh, them Germans. BTW, I'm the one who came up with the topic. I asked about std::basic_istream as well but the answer will probably be the same, so, it's easier to talk only about std::basic_ostream. Björn
[toc] | [prev] | [next] | [standalone]
| From | Pete Becker <pete@versatilecoding.com> |
|---|---|
| Date | 2011-05-19 18:11 -0400 |
| Message-ID | <201105191811177950-pete@versatilecodingcom> |
| In reply to | #5187 |
On 2011-05-19 17:27:52 -0400, Björn said: > Alf P. Steinbach /Usenet wrote: > >> * Stefan Ram, on 19.05.2011 00:54: >>> The output operator "<<" for operands of type »::std::ostream« and >>> »char« (in this order) seems to be defined as a non-member, while >>> for »double« it seems to be defined as a member. >> >> This may depend on which standard you're talking about. I haven't >> checked but as I recall some of the issues related to this were >> fixed in C++0x. Which is on its way Real Soon Now. > > In the current draft N3242 from 2011-02-28 it is still as described. Yes, that hasn't been changed. -- Pete Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The Standard C++ Library Extensions: a Tutorial and Reference (www.petebecker.com/tr1book)
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c++
csiph-web