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

标签 c++ stdmove

我遇到了一些 code

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;
}

我有一个问题。为什么我们必须在 init 上使用 std::move,即使 initint

最佳答案

你是对的,移动一个 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;
}

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

关于c++ - std::move 一个将被覆盖的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61259389/

相关文章:

c++ - 为什么 std::move() 在 C++ 中工作?

c++ - 在 C++ 中到达 .eof() 后如何返回到文件的开头?

c++ - 如何在不更改代码的情况下强制对 Visual C++ 中的 POD 类型进行值初始化?

C++ OpenSSL HMACSHA1 可以工作,但不是我想要的

C++ 将 unique_ptr 移动到结构成员

c++ - 为什么 std::move 不在默认 move 构造函数中将源变量更改为默认值?

c++ - 尽管参数是 r 值引用,为什么要使用 std::move

c++ - 如何用 QDBus 解析 {String 的字典,{String,Variant}} 的字典?

c++ - 如何禁用 Windows 上的调试断言对话框?

c++ - 什么是 std::move(),什么时候应该使用它?