我试图理解C ++移动语义,std::move()
和rvalue引用。
我已经实现了这个例子。
#include <iostream>
#include <vector>
int main()
{
int totalSize = 6;
std::vector<double> oldData{ 10, 20, 30 };
oldData.resize(totalSize, 0);
std::vector<double> newData(std::move(oldData));
return 0;
}
我想知道这实际上是移动矢量oldData
到newData
还是正在复制发生在引擎盖下。
假设您将无限循环修复为:
for(unsigned i = 0; i < totalSize - oldData.size(); ++i) oldData.push_back(0);
并写下类似的东西:
for(unsigned i = oldData.size(); i < totalSize; ++i)
oldData.push_back(0);
或者,甚至更好:
oldData.resize(totalSize, 0);
然后std::move
将所有数据从oldData
移动到newData
。这是a quote from cppreference:
6)移动构造函数。使用move语义构造具有其他内容的容器。分配器是通过属于其他分配器的移动构造获得的。移动后,其他保证为空()。
7)分配器扩展的移动构造函数。使用alloc作为新容器的分配器,从其他容器移动内容;如果alloc!= other.get_allocator(),则会导致元素移动。 (在这种情况下,移动后其他不保证是空的)
在您的特定情况下,向量具有默认分配器,这意味着仅应用第(6)项。但是,如果有人通过分配器,那么事情会变得更有趣。
以下是关于复杂性主题的其余内容:
6)常数。
7)线性如果alloc!= other.get_allocator(),否则为常量。
同样,在您的情况下,复杂性是O(1),但对于分配器,事情变得更有趣。
结论:内部表示必须在O(1)中移动一定数量的指针,而不是逐个移动元素。可以使用一个具有容量和大小整数的指针或三个指针(开始,结束和容量结束)来实现向量。对于所有这些实现,移动是一个简单的玩指针。
但是,如果提供了非默认分配器并且两个向量使用不同的分配器对象,则必须逐个移动或复制这些值。