I gave a talk on universal references at this year's C++ and Beyond, and a video of that talk should go live sometime this month. (I'll let you know when.) I also wrote an article on the topic for ACCU's Overload, and the issue with the article (PDF) has just been published. This is from the beginning of that article:
Given that rvalue references are declared using “&&”, it seems reasonable to assume that the presence of “&&” in a type declaration indicates an rvalue reference. That is not the case:I hope you find the article both interesting and useful.
Widget&& var1 = someWidget; // here, “&&” means rvalue reference auto&& var2 = var1; // here, “&&” does not mean rvalue reference template<typename T> void f(std::vector<T>&& param); // here, “&&” means rvalue reference template<typename T> void f(T&& param); // here, “&&” does not mean rvalue referenceIn this article, I describe the two meanings of “&&” in type declarations, explain how to tell them apart, and introduce new terminology that makes it possible to unambiguously communicate which meaning of “&&” is intended. Distinguishing the different meanings is important, because if you think “rvalue reference” whenever you see “&&” in a type declaration, you’ll misread a lot of C++11 code.
Scott
Can't wait to read this, and looking forward to the video!
ReplyDeleteI believe there is a small hole in the article
ReplyDeletetemplate
class Widget {
public:
void foo( T&& arg );
};
Here arg can be both rvalue and lvalue ref. If T is R&, arg is R&, no?
@Gennadiy: Yes, given
ReplyDeletetemplate<typename T>
class Widget {
public:
void foo( T&& arg );
};
the class Widget<type&> would contain the function
void Widget::foo(type& arg);
instead of
void Widget::foo(type&& arg);
Thanks for pointing this out.