首页 > 解决方案 > 什么样的引用应该在 C++ 中使用具有移动语义的 move() 成员函数?

问题描述

在实现 C++11move()方法以避免复制之前。move()在 C++11 中引入了 move 语义,但有时拥有方法并从 move-constructor 和 move 调用它更容易operator=。该move()方法可以通过普通引用(l-reference)或r-reference来获取对象。

我们应该使用什么参考?哪个选项更好/更清洁/更快/...?

这是具有两种可能性的示例代码(需要 C++20):

#include <iostream>
#include <ranges> // copy, size
#include <memory> // unique_ptr
using namespace std;

constexpr bool MOVE_WITH_LREF_IS_BETTER = true;

class Array
{
    size_t size_ = 0;
    unique_ptr<int[]> data_;

public:
    template<size_t N>
    Array(const int (&src)[N]) : size_(N), data_(make_unique<int[]>(N))
    {
        std::ranges::copy(src, data_.get());
    }

    Array(Array&& src)
    {
        if constexpr(MOVE_WITH_LREF_IS_BETTER)
            move_lref(src);
        else
            move_rref(std::move(src));
    }

    Array& operator=(Array&& src)
    {
        if constexpr(MOVE_WITH_LREF_IS_BETTER)
            move_lref(src);
        else
            move_rref(std::move(src));
        return *this;
    }

    void move_lref(Array& src)
    {
        if (&src != this)
        {
            size_ = exchange(src.size_, 0);
            data_ = std::move(src.data_);
        }
    }
    void move_rref(Array&& src)
    {
        if (&src != this)
        {
            size_ = exchange(src.size_, 0);
            data_ = std::move(src.data_);
        }
    }
    auto operator[](size_t index) const
    {
        if (index >= size_)
        {
            throw out_of_range("");
        }
        return data_[index];
    }
};

int main()
{
    constexpr int srcArray[] = { 1, 9, 9, 0 };

    Array a(srcArray);
    Array b = std::move(a);

    for (size_t i=0; i < ranges::size(srcArray); ++i)
        cout << b[i] << "\n";
}

标签: c++11move-semanticsmove-constructormove-assignment-operator

解决方案


推荐阅读