SoFunction
Updated on 2025-04-13

Relationships and differences between lvalue references, rvalue references, universal references in C++

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&&,inTIt 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.
  • passstd::moveYou 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.