C++11 连续存储容器和移动语义

C++11 连续存储容器和移动语义,c++11,vector,move,semantics,contiguous,C++11,Vector,Move,Semantics,Contiguous,容器如何既连续又同时支持移动语义 std::vector的示例: 使用std::在左值上移动调用push_back()时: std::vector<MyClass> v; MyClass obj; MyClass obj2; vt.push_back(std::move(obj)); vt.push_back(std::move(obj2)); 您只需要阅读更多关于移动语义的内容:-) 移动对象不会更改对象本身的地址。它只调用对象的另一个实例的移动构造函数(或赋值运算符,等等,

容器如何既连续又同时支持移动语义

std::vector的示例: 使用std::在左值上移动调用push_back()时:

std::vector<MyClass> v;

MyClass obj;
MyClass obj2;

vt.push_back(std::move(obj));
vt.push_back(std::move(obj2));

您只需要阅读更多关于移动语义的内容:-)

移动对象不会更改对象本身的地址。它只调用对象的另一个实例的移动构造函数(或赋值运算符,等等,取决于上下文),该实例被传递给要移动的实例

在本例中,向量确实在其内部存储器中创建了两个
MyClass
对象,每个
推回一个
。但是对于第一个,它不是调用复制构造函数并传递
obj
(通过
MyClass const&
),而是调用move构造函数并将右值引用(
MyClass&&
)传递给
obj
。然后由该构造函数将
obj
对象的内容移动到向量中的内容

换句话说,对象本身是在向量中创建的,并且只移动了对象的内容(对于每种类型来说,“移动”对象的含义可能不同,因此移动构造函数的工作是进行实际移动)


请注意,即使使用
std::move
,也可能不会调用move构造函数——例如,可能没有调用move构造函数,或者可能有一个不是
noexcept
(在这种情况下,
std::vector
不能在所有情况下都使用它而不违反其异常安全保证)。

您的
std::move
是一个强制转换,这是一个无条件强制转换,如果您没有使用正确的语义,它很容易在副本中衰减

换句话说,编写
std::move
不能保证除了
t&
类型之外的任何东西,该类型本身不能保证移动语义

MyClass obj;
MyClass obj2;

vt.push_back(std::move(obj));
vt.push_back(obj2);