Topic: Binding refs to temporaries etc.. (Was: Printing part of a string)
Author: gurnec@my-dejanews.com
Date: 1998/09/29 Raw View
Christopher Eltschka wrote in message
<360A3A1D.8F27C286@physik.tu-muenchen.de>...
>Valentin Bonnard wrote:
>>
>> I know it has been beaten to death, but what about the
>> following:
>>
>> - binding to the result of an implicit conversion is illegal
>> - binding to any other rvalue is ok
<clip>
>What about:
>
> foo(1L); // no conversion needed, since type matches
> foo(long_var++); // dito
>
> void bar(int&);
> bar(1); // again, no conversion needed
I agree, but this is solved easily enough. Only allow this type of
binding on class types. More specifically,
(definition: a reference-compatible type is one that could potentially be
*directly* bound to the reference in question; not exactly right, but
close enough)
A reference-compatible rvalue can be directly bound to a non-const
reference only if it is of class type.
This would have the nice symmetry that Valentin Bonnard mentioned:
rvalues of class type would be modifialbe through non-const member
funcions and also by functions taking non-const references, however
non-class type rvalues would remain non-modifiable.
This modification would have the same potential awkwardness that calling
non-const member functions on rvalues currently has:
class MyComplex;
void square_it(MyComplex& toBeSquared);
. . .
void foo() {
// doesn't make much sense, but possible:
MyComplex().square_me();
// also makes little sense, and/but currently illegal:
square_it(MyComplex());
}
NEW (related) SUBJECT, valarray defect:
All this talk of references reminds me of a defect in the standard
regarding valarray's assignment operators and constructors. The change
above suggests a simple way to fix it. First, a little review:
One of valarray's operator[]'s returns a slice_array rvalue. Since
slice_array has reference semantics to the valarray, it declares a
private copy ctor to prevent copying. It was the intent to allow
passing this return value to another valarray's ctor, which takes the
type const slice_array&. Here is the problem:
The standard says that when a reference-compatible rvalue of class type
is bound to a const reference, it can either be directly bound or a new
temporary can be created. Because a temporary MIGHT be created, the
copy ctor must be visible. However, slice_array's copy ctor is
intentionally hidden. Therefore, it can never be passed to valarray's
ctor (or its assignment operator). This is also true of gslice_array's,
mask_array's, and indirect_array's.
With the change described by Valentin Bonnard, the solution is simple:
change valaray's ctors and assignment operators to take non-const
references. A direct binding is then required and the *_array's copy
ctor need not be visible.
A related question:
Why is a temporary allowed in the case of binding a reference-compatible
rvalue of class type to a const reference? Why not just require a
direct binding?
-Chris Gurnee
Just for reference, relevant clauses in the standard:
Valarray: 26.3.2.1 and 26.3.2.2
References: 8.5.3
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ 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: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/09/24 Raw View
Valentin Bonnard wrote:
>
> I know it has been beaten to death, but what about the
> following:
>
> - binding to the result of an implicit conversion is illegal
> - binding to any other rvalue is ok
>
> Advantages:
[...]
> - it still catches the errors I want to catch:
>
> void foo (long&);
> foo (1);
What about:
foo(1L); // no conversion needed, since type matches
foo(long_var++); // dito
void bar(int&);
bar(1); // again, no conversion needed
---
[ 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: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1998/09/22 Raw View
I know it has been beaten to death, but what about the
following:
- binding to the result of an implicit conversion is illegal
- binding to any other rvalue is ok
Advantages:
- it allows obviously correct cases like
Siemel Naran wrote:
> On 18 Sep 1998 19:51:17 GMT, David Harmon <source@netcom.com> wrote:
> >On 17 Sep 1998 20:40:57 GMT, sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
>
> >>> string first, middle, last;
> >>> stringstream(name) >> first >> middle >> last;
- it still catches the errors I want to catch:
void foo (long&);
foo (1);
- it would restore the equivalence between implicit and explicit
function arguments:
struct foo {
foo& operator<< (int);
foo (bar);
};
foo& operator<< (foo&, long);
foo () << 3 << 3L; // legal now, still legal
foo () << 3L << 3; // illegal now, would be legal
bar () << 3L; // illegal, no convertion allowed on implicit
// this argument
bar () << 3; // illegal, can't bind to ...
Problems: ???
--
Valentin Bonnard mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://pages.pratique.fr/~bonnardv/
[ 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 ]