Re: (N2118)Rvalue reference may create a loophole in the type system
In article <1185425242.169428.219920@i38g2000prf.googlegroups.com>,
frege <gottlobfrege@gmail.com> wrote:
On Jul 25, 7:10 pm, jcof...@taeus.com (Jerry Coffin) wrote:
If you really want 'r' to be an rvalue reference to the same type as
'd', shouldn't you really use auto (in its new meaning) to express that
intent directly?
Speaking of auto and rvalue refs, I've been meaning to ask (to Howard
mostly, based on a slide from the BoostCon)...
void f(int i)
{
}
void f(int const & cr)
{
}
void f(int && r)
{
auto q = r;
decltype(r) s = r;
f(r);
f(q);
f(s);
f(std::move(r));
//etc
}
what are the types of q and s? which f is called in each case?
Partial answer:
f(int) and f(int const &) are ambiguous (under C++03 and C++0X).
I don't know what auto does (haven't kept up with it, and I don't
believe it is in the draft yet).
Otherwise, every use of r, q, and s inside of f() will be treated as an
lvalue, not as an rvalue. There's only two places where named variables
will be treated as rvalues: both of those places are where copy elision
is already legal today.
1. Returning a local auto-storage variable by value.
2. Throwing a local auto-storage variable.
what about
template <typename T>
void f(T t)
{
auto q = t;
decltype(t) s = t;
//...
}
for most types T, I suspect q and s are of type T, but I'm not so sure
when T is a &&.
By today's rules, if you:
void g()
{
int i = 0;
int& ir = i;
f(ir);
}
T is deduced as int, not int&. Same answer if you change ir:
int&& ir = i;
Summary: There are only a few places where && behaves differently from
&. If in doubt, assume that && behaves the same as &, and you'll be
correct more often than not.
so are these 3 functions different:
template <typename T>
void f1(T t)
{
f(t);
}
template <typename T>
void f2(T t)
{
auto q = t;
f(q);
}
template <typename T>
void f2(T t)
{
decltype(t) q = t;
f(q);
}
I'd like to think that the creation of a temporary doesn't (typically
- ie for regular types) change anything, but does it when T is an
rvalue ref?
All of those should behave identically, treating t and q as lvalues.
If you have a name for it (a variable name), it is an lvalue. It will
prefer lvalue references in overload resolution.
If you don't have a name for it (such as the return value of a
function), then it is an rvalue ... with one exception: unnamed lvalue
references are lvalues.
A& an_lvalue();
A&& an_rvalue();
A another_rvalue();
char source(const A&);
int source(A&&);
int main()
{
A a;
an_lvalue() = a; // ok
an_rvalue() = a; // compile time error
another_rvalue() = a; // compile time error
A&& ar = a; // ar is an lvalue, it has a name "ar"
ar = a; // ok
char c1 = source(ar); // returns char, not int
char c2 = source(an_lvalue()); // returns char
int i1 = source(an_rvalue()); // returns int
}
-Howard
---
[ 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://www.comeaucomputing.com/csc/faq.html ]