Rvalue References
Declaration | Binds to | Meaning |
|---|---|---|
T& x | lvalues only | A regular reference to an existing, named object |
const T& x | lvalues and rvalues | Read-only view; the classic way to accept "anything" before C++11 |
T&& x | rvalues only | An rvalue reference; signals the callee may steal x's resources |
Overloading on lvalue-ref vs rvalue-ref
Overload resolution: which version gets called?
#include <iostream>
#include <string>
void process(const std::string& s) {
std::cout << "lvalue overload (copying): " << s << "\n";
}
void process(std::string&& s) {
std::cout << "rvalue overload (can steal): " << s << "\n";
}
std::string makeGreeting() {
return "hello";
}
int main() {
std::string name = "Ada";
process(name); // lvalue -> const std::string& overload
process(makeGreeting()); // temporary -> std::string&& overload
process(std::move(name)); // cast to rvalue -> std::string&& overload
return 0;
}Universal (forwarding) references
A universal reference and std::forward
#include <iostream>
#include <utility>
template <typename T>
void relay(T&& x) {
// std::forward preserves whether the original argument was
// an lvalue or an rvalue when passing it along.
process(std::forward<T>(x));
}
// (Assume 'process' overloads exist as in the example above.)T&& declares an rvalue reference, which binds only to temporaries.
Overloading on T& vs T&& lets a function behave differently for named variables vs temporaries.
template<typename T> void f(T&& x) is a distinct, more advanced feature: a universal/forwarding reference.
std::forward preserves the original value category of a forwarded argument in generic code (perfect forwarding).