Re: Template argument as rvalue reference
Am 27.10.2012 21:12, schrieb Juha Nieminen:
SG <sgesemann@gmail.invalid> wrote:
If you have a non-templated rvalue reference parameter,
you can't give it an lvalue. You'll get a compile error.
What is an "rvalue reference parameter"?
Something like this:
void foo(int&& i);
If you try to give an lvalue to that, it gives an error.
Right. The thing is, if you write
template<class T> void blah(T&& x) {...}
x is not necessarily an rvalue reference parameter. It looks like one.
And it may be one depending on what T is. But is also may be an lvalue
reference. The reference collapsing rule "&+&&=&" makes x an lvalue
reference in case T is an lvalue reference type, otherwise x is an
rvalue reference. That's reference collapsing.
In addition to reference collapsing we have a special template argument
deduction rule which automatically picks the "right T" to make
initializing a parameter of type T&& possible. That is, if the argument
was an lvalue, the corresponding template type parameter is deduced to
be an lvalue reference type, otherwise it is a non-reference type. Why?
Because these rules are the rules they came up with to enable "perfect
forwarding".
I must admit, I do not know the new standard enough to understand what
exactly is going on here, and why it makes a difference (and why you need
a typedef):
typedef int& foo;
void bar(foo&& x);
The syntax does not allow "int& && x". I guess that is because there
would be no point in allowing it since you could just as well write
"int& x".
If you havn't already seen one of Scott Meyers' latest talks about
rvalue references, I encourage you to take a look.
HTH,
SG