Rvalue reference parameters and template functions
If I define a function which accepts an rvalue reference parameter:
template <typename T>
void fooT(T &&x) {}
I can call it, using GCC 4.5, with either a
, ar
, or arr
:
int a, &ar = a, &&arr = 7;
fooT(a); fooT(ar); fooT(arr);
However, calling a similar, non-te开发者_StackOverflow社区mplate function,
void fooInt(int &&x) {}
with any of those three arguments will fail. I was preparing to strengthen my knowledge of forward
, but this has knocked me off course. Perhaps it's GCC 4.5; I was surprised to find that the first example from A Brief Introduction to Rvalue References also gives a compile error:
A a;
A&& a_ref2 = a; // an rvalue reference
The behavior of deduction in template parameters is unique, and is the reason your template version works. I've explained exactly how this deduction works here, in the context of another question.
Summarized: when the argument is an lvalue, T
is deduced to T&
, and T& &&
collapses to T&
. And with the parameter at T&
, it is perfectly valid to supply an lvalue T
to it. Otherwise, T
remains T
, and the parameter is T&&
, which accepts rvalues arguments.
Contrarily, int&&
is always int&&
(no template deduction rules to coerce it to something else), and can only bind to rvalues.
In addition to GMan's correct answer A Brief Introduction to Rvalue References has an incorrect example because it was written prior to a language change which outlawed:
A a;
A&& a_ref2 = a; // an rvalue reference (DISALLOWED in C++11)
Despite this change in the language, the main uses cases described in the article (move and forward) are still explained correctly in the article.
Update: Oh, and the same article was originally published here with (imho) slightly better formatting.
精彩评论