我跑了一些代码
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即使init是int?
你是对的,移动一个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。)
| 归档时间: |
|
| 查看次数: |
98 次 |
| 最近记录: |