根据N3485§23.3.2.2:
(...)数组的隐式移动构造函数和移动赋值运算符要求T 分别为MoveConstructible或MoveAssignable.
因此,std::array如果元素的类型支持,则支持移动语义.大!
但是,这究竟意味着什么?我倾向于将这种类型描述为提供符合STL标准的接口的更安全的数组版本,但是,如果这是真的,那么std::array移动构造它的元素怎么样?我可以用普通数组做同样的事情吗?
Mik*_*our 26
但是,这究竟意味着什么?
这意味着,如果元素类型是可移动的,那么数组类型也是如此.
std::array<movable, 42> move_from = {...};
std::array<movable, 42> move_to = std::move(move_from); // moves all the elements
Run Code Online (Sandbox Code Playgroud)
我倾向于将此类型描述为提供符合STL标准的接口的阵列的更安全版本
并不是的.它是数组的包装器,赋予它与聚合类相同的语义 - 包括复制和移动它的能力.
如何
std::array移动 - 构建其元素?
与任何其他聚合完全相同.它的隐式移动构造函数将移动构造其所有成员,包括任何成员数组的元素.
我可以用普通数组做同样的事情吗?
只有将它包装在类类型中时std::array才会这样.
Rei*_*ica 21
移动a std::array与移动a不同std::vector.当一个移动std::vector到另一个时,它(有时*)可以简单地重新定位内部指针并避免操纵元素.
有了std::array,这当然是不可能的 - 它的元素具有自动存储持续时间,它们实际上包含在对象内.但是,它们中的每一个仍然可以被移动,这就是移动操作std::array所做的事情**.
*假设分配器兼容并且不禁止此操作
**std::vector当缓冲区不能仅由目标向量重新拥有时,这也是你得到的.
(非联合)类的默认移动构造函数执行成员移动.移动原始数组数据成员意味着移动每个数组的元素,请参阅[class.copy]/15.
因此,您可以通过将原始数组放在类中来移动它:
struct wrap
{
std::string arr[25];
};
auto w = wrap();
auto m = std::move(w); // moves the 25 `std::string`s
Run Code Online (Sandbox Code Playgroud)
您还可以手动调用元素的移动构造函数,例如:
std::string a[3] = { /*...*/ };
std::string b[3] = {std::move(a[0]), std::move(a[1]), std::move(a[2])};
Run Code Online (Sandbox Code Playgroud)
如果std::array包含原始数组,则不指定.但是,它确实包含数据成员value_type,因为它保证是一个聚合.调用移动构造函数时,将按照上述方法移动这些数据成员.
如果a的数据成员std::array不是MoveConstructible,则实例化其移动构造函数将失败.
| 归档时间: |
|
| 查看次数: |
6643 次 |
| 最近记录: |