The relationship and difference between lvalue reference, rvalue reference, universal reference
In C++, lvalue reference, rvalue reference and universal reference are three different reference types. Their main differences are the bound object type and lifecycle management.
Below are their detailed explanations and sample code.
1. Lvalue Reference
The lvalue reference is bound to an lvalue (i.e. an object with a name and can take an address). LV references are often used to pass parameters or extend the life of an object.
#include <iostream> void print(int& x) { std::cout << "Lvalue reference: " << x << std::endl; } int main() { int a = 10; int& ref = a; // Lvalue reference print(a); // Pass lvalue return 0; }
2. Rvalue Reference
The rvalue reference is bound to an rvalue (i.e. a temporary, soon to be destroyed object). Rvalue references are often used to implement mobile semantics and perfect forwarding.
#include <iostream> void print(int&& x) { std::cout << "Rvalue reference: " << x << std::endl; } int main() { int a = 10; print(10); // Pass the right value print(std::move(a)); // Use std::move to convert lvalue to rvalue return 0; }
3. Universal Reference
Universal references are concepts introduced by C++11. They usually appear in templates and can be bound to lvalues or rvalues. The syntax form of universal reference isT&&
,inT
It is a template parameter.
#include <iostream> template<typename T> void print(T&& x) { std::cout << "Universal reference: " << x << std::endl; } int main() { int a = 10; print(a); // Pass lvalue print(10); // Pass the right value return 0; }
4. Differences and Relationships
- Lvalue reference: Only bound to lvalues, usually used to pass parameters or extend the life of an object.
- Rvalue reference: Only bound to rvalues, usually used to implement mobile semantics and perfect forwarding.
- Universal Quote: Can be bound to lvalues or rvalues, usually used in templates to implement common code.
5. Sample code
Here is a comprehensive example showing the use of lvalue references, rvalue references, and universal references:
#include <iostream> #include <utility> // for std::move // Lvalue referencevoid printLvalue(int& x) { std::cout << "Lvalue reference: " << x << std::endl; } // Rvalue referencevoid printRvalue(int&& x) { std::cout << "Rvalue reference: " << x << std::endl; } // Universal Quotetemplate<typename T> void printUniversal(T&& x) { std::cout << "Universal reference: " << x << std::endl; } int main() { int a = 10; // Lvalue reference printLvalue(a); // Rvalue reference printRvalue(10); printRvalue(std::move(a)); // Universal Quote printUniversal(a); // Pass lvalue printUniversal(10); // Pass the right value return 0; }
Summarize
- The lvalue reference is used to bind the lvalue, and the rvalue reference is used to bind the rvalue.
- Universal references can be bound to lvalues or rvalues, and are usually used in templates.
- pass
std::move
You can convert an lvalue to an rvalue, thereby using an rvalue reference.
These reference types are very important in C++, especially when implementing efficient memory management and common code.
The above is personal experience. I hope you can give you a reference and I hope you can support me more.