Topic: Non-const reference to rvalue (was Printing part of a string)


Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/09/22
Raw View
Paul D. DeRocco wrote:

[...]

> Here's one possible way, in some future incarnation of C++, to signal to
> the compiler that a particular (non-member) operation has side effects,
> and that should therefore be allowed on an rvalue:
>
>         ostream& operator>>(mutable ostream& os, int v);

you meant istream& operator>>(mutable istream& is, int v); didn't you?

>
> Thus, since os isn't const, it can bind to a non-const ostream, but
> "mutable" would allow it to bind to an rvalue, as though "const" had
> been specified.

I'd prefer a slightly different mechanism, which would also make
ostrstreams more usable:

pass operator<<(pass ostream& os, int v);

would mean "Take a reference on the ostream os (which may be temporary),
perform the operation, and then use the *original* object as return
value (this especially includes the original type); that is, the
function
itself returns nothing, but the caller behaves as if the original
object were passed.

and then use it like the following:

string s=(istrstream << "i has the value" << i).str();

which is not possible today not only because of the binding rule,
but also because operator<< today returns a reference to istream,
which obviously has no str() member.

C operator+(C xonst& c1, C const& c2)
{
  return C(c1)+=c2;
}

Currently, if operator+= is not inline, the compiler has no way to
know that it is reusing the temporary created by C(c1) for the return
value. If, however, the operator+= were defined as

pass C::operator+=(C const& other) pass;

the compiler would be aware of that, and could optimize it.

The semantics of the "pass" specifier would be "make a modification
to the object and continue using it". Since return *this is quite
common in C++ (think of operator=, operator +=, etc.), this could
be useful in many places. Also, it would simplify coding since
the extra return *this would not be needed any more.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/09/19
Raw View
David Harmon wrote:
>
> On 17 Sep 1998 20:40:57 GMT, sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
> wrote:
>
> >On Thu, 17 Sep 1998 20:35:49 GMT, David Harmon <source@netcom.com>
> >wrote:
> >
> >>      string first, middle, last;
> >>      stringstream(name) >> first >> middle >> last;
> ...
> >which results in an error, "temp 'stringstream(name)' used in call to
> >op>>(...)".
>
> Well, er, uhm, I HATE THAT RULE!  Caught by it again.
>
> As far as I am concerned, the example I posted is entirely reasonable
> and legitimate.  The mouldy old compiler I presently use accepts it
> (except I am using strstream) without a problem. The C++ committee
> made
> a change which breaks my existing code, for no good reason that I am
> aware of.

The problem is that there is no distinction made between mutating
operations with and without side-effects. In general, it makes no sense
to mutate a temporary, which is why they added the rule. For instance,
the statement "1+1=3;" could be taken to mean that 1 is added to 1,
creating a temporary value of 2, which is then overwritten with 3, and
then thrown away. But the fact that it is thrown away makes it useless,
and therefore illogical. But on class types, some mutating operations
have important side-effects that persist beyond the lifetime of the
object, thus making certain non-const operations on rvalues meaningful.
However, there is no way to allow such operations without allowing the
meaningless ones that have no side effects as well.

Note that this rule doesn't hold if the rvalue is the implicit object
parameter of a member function. If stringstream had defined the various
forms of operator>> and operator<< as member functions, the above
construct would be legal.

Here's one possible way, in some future incarnation of C++, to signal to
the compiler that a particular (non-member) operation has side effects,
and that should therefore be allowed on an rvalue:

 ostream& operator>>(mutable ostream& os, int v);

Thus, since os isn't const, it can bind to a non-const ostream, but
"mutable" would allow it to bind to an rvalue, as though "const" had
been specified.

--

Ciao,
Paul


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]