右值引用主要用于移动语义(Move semantics)和完美转发(Perfect forwarding)

Move semantics

Move semantics能转移一个对象到另一个对象上,避免不必要的内存拷贝,被拷贝对象不能在其它地方被引用。要实现Move semantics只要给类定义移动构造函数和可选的移动赋值操作:

class Memory {
public:
    Memory(Memory&& other) noexcept {
        _data = other._data;
        _length = other._length;
        other._data = nullptr;
        other._length = 0;
    }
    Memory& operator=(Memory&& other) noexcept {
        if (this != &other) {
            delete[] _data;
            _data = other._data;
            _length = other._length;
            other._data = nullptr;
            other._length = 0;
        }
        return *this;
    }
private:
    void *_data{nullptr};
    int _length{0};
}

Perfect forwarding

Perfect forwarding主要为了减少重载函数,主要是泛型函数用引用类型作为参数。

struct W
{
   W(int&, int&) {}
};

struct Z
{
   Z(const int&, const int&) {}
};

template <typename T, typename A1, typename A2>
T* factory(A1& a1, A2& a2) {
   return new T(a1, a2);
}

int a = 4, b = 5;
W* pw = factory<W>(a, b); // OK
Z* pz = factory<Z>(2, 2); // Valid cause 2 is right value

把上面的泛型函数参数改成右值引用就能解决这个问题:

template <typename T, typename A1, typename A2>
T* factory(A1&& a1, A2&& a2)
{
   return new T(std::forward<A1>(a1), std::forward<A2>(a2));
}
Z* pz = factory<Z>(2, 2); // OK

References: https://learn.microsoft.com/en-us/cpp/cpp/rvalue-reference-declarator-amp-amp?view=msvc-170