主要观点:除了使用 P1144 式或偶尔 P2786 式的简单可重定位库外,还有至少两个使用P1029R2式“移动后简单可销毁”的库;展示了is_trivially_relocatable
和is_trivially_destructible_after_move
的区别;通过std::list
和std::deque
的例子说明不同实现中这两个特性的不同;提到许多类型在移动构造后可简单销毁,但在移动赋值后不可简单销毁,使用is_trivially_destructible_after_move
时要谨慎,且这些特性对于从T
类型“移动”到不同U
类型的操作不适用。
关键信息:
- 提到的两个实现
is_trivially_destructible_after_move
的库:Domagoj Šarić 的psiha/vm定义了trait moved_out_value_is_trivially_destructible
;Artur Bać 的arturbac/small_vectors定义了concepts::relocatable
。 std::list
的两种实现策略:微软 STL 的“哨兵节点”策略,每个list
结尾有额外的分配节点(哨兵);libstdc++和 libc++的“伪节点”策略,list
对象自身包含“伪”节点,由 prev/next 指针对组成。std::deque
在 libstdc++中is_trivially_relocatable<std::deque<int>>
为true
但is_trivially_destructible_after_move<std::deque<int>>
为false
。- 许多类型在移动构造后可简单销毁但在移动赋值后不可简单销毁,如 libstdc++的
string
。
重要细节:
- 标准 C++中 P1144 式库算法
uninitialized_relocate
的定义。 std::list
在不同实现下移动构造和销毁的过程及指针变化。- 代码示例中展示的各种操作及可能出现的问题,如
inplace_vector
的operator=
在T
为 libstdc++的string
时会泄漏内存,transfer
函数在特定类型时会泄漏内存等。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。