Re: Shooting yourself in the foot with rvalue references
On 15 Mai, 03:40, Matthias Hofmann wrote:
[...] Please
take a look at the following code:
void f( int&& rri )
{
g( rri );
}
void g( int& ri )
{
ri = 4;
}
int main()
{
int&& rri = 5;
rri = 4;
f( 5 );
return 0;
}
According to C++0x, an rvalue reference that has a name is an lvalue. So in
my example, the first line of code in main() aims at your foot and the
second line bluntly pulls the trigger.
I don't see it. Where is the harm here?
The call to f() is a shot around the
corner, which is more practical, but the bullet goes through the same whole
in your foot.
I don't see it.
I have been desperately looking for a rule that says that C++0x does not
have such a severe security whole,
What security hole? It used to have one. But that got closed (and now
the initialization of rvalue references has been restricted to rvalues
and things convertible into temporary objects of appropriate types).
So, basically, an rvalue reference can only refer to something that
may be modified without anybody caring about it. Once you have a named
rvalue reference, you have the chance of referring to the object
multiple times. This is a characteristic of lvalues. So, for security
reasons, a named rvalue reference is an lvalue expression (so that no
accidental modification/movement can happen).
Basically, as a beginner, you have to keep the following three things
in mind:
(1) As a rule of thumb: If you feel the need to write a function which
returns an rvalue reference, it is _probably_ the wrong thing to do.
Rvalue references are references. Returning references to function-
local objects is still wrong, no matter what kind of reference it is.
Special exceptions: std::move, std::forward.
(2) Keep in mind that the pattern T&& where T is a function template's
deducible type parameter is a special "catch everything"-pattern. It
will catch lvalues as well. Not because an rvalue references binds to
an lvalue but because of a special template argument deduction rule
and because of reference collapsing. Keep in mind that T will be
deduced to be an lvalue reference in case you use an lvalue expression
as function argument. In that case T&& will also be an lvalue
reference (due to reference collapsing).
(3) If you're not sure how to use rvalue references, don't bother or
limit yourself to writing move constructors and move assignment
operators for your custom types.
Other than that, the current incarnation of rvalue references are
rather harmless.
[...] Or is this
only in compliance with the first amendment to the C++ standard, which says
that "the committee shall make no rule that prevents C++ programmers from
shooting themselves in the foot"?
Again, why do you think your examples constitute any harm? Where is
the harm here?
--
SG
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]