std::move 一个将被覆盖的变量

Mik*_*ail 3 c++ stdmove

我跑了一些代码

template<class InputIt, class T>
constexpr // since C++20
T accumulate(InputIt first, InputIt last, T init)
{
    for (; first != last; ++first) {
        init = std::move(init) + *first; // std::move since C++20
    }
    return init;
}
Run Code Online (Sandbox Code Playgroud)

我有个问题。为什么我们必须使用 std::move oninit即使initint

Hol*_*Cat 5

你是对的,移动一个int和复制它没有什么不同。

在这里,std::move仅当T的重载operator+对于左值和右值的行为不同时才变得有用。

我从未听说过这样的类,但我想它可能对+以巧妙方式重载的动态数组有用:

struct Vec
{
    std::vector<int> elems;
};

// Returns a completely new vector.
Vec operator+(const Vec &a, const Vec &b)
{
    assert(a.size() == b.size());
    Vec ret(a.size());
    for (std::size_t i = 0; i < a.size(); i++)
        ret.elems[i] = a.elems[i] + b.elems[i];
    return ret;
}
// Reuses storage of `a`.
Vec operator+(Vec &&a, const Vec &b)
{
    assert(a.size() == b.size());
    for (std::size_t i = 0; i < a.size(); i++)
        a.elems[i] += b.elems[i];
    return std::move(a);
}
// Reuses storage of `b`.
Vec operator+(const Vec &a, Vec &&b)
{
    return std::move(b) + a;
}
// Reuses storage of `a`.
Vec operator+(Vec &&a, Vec &&b)
{
    return std::move(a) + b;
}
Run Code Online (Sandbox Code Playgroud)

编辑:显然std::string做了类似的事情:+如果可能,它会重用其中一个操作数的存储。(感谢@FrançoisAndrieux 和@Artyer。)

  • [`std::operator+(std::string&amp;&amp;, const std::string&amp;)`](https://en.cppreference.com/w/cpp/string/basic_string/operator%2B) 存在。一般来说,我假设它将被实现为“return std::move(lhs += rhs)” (5认同)