这是一个简单的 C++20 兼容constexpr
的Optional
类型:
- 包含构造函数、移动构造函数、拷贝构造函数、赋值运算符重载、交换函数和析构函数等。
- 行为类似于
std::optional
,但有一个重要语义差异,即它是“可替换的”,通过复制和交换而非赋值来实现交换操作,这样就不会调用T
的赋值运算符,即使T
的赋值运算符有问题也没关系。 - 要求
is_trivially_relocatable_v<T> == is_trivially_relocatable_v<Optional<T>>
,对于像tuple<int&>
这样具有“奇怪”赋值运算符的类型,可以通过特定的模板特化来使其可轻松移动。
C++26 使情况变得更复杂:
- 存在“P1144”和“P2786”两种“简单移动”模型,P2786 要求处理两个特性,每个特性都有一些问题。
- 不再是
Optional<T>
的可简单移动性等价于T
的可简单移动性,例如对于Poly
和Holder
的组合,std::is_trivially_relocatable_v<Holder>
在 P2786 中为真,但std::is_trivially_relocatable_v<Optional<Holder>>
可能为真或假。 replaceable_if_eligible
关键字具有“钝刀”语义,编译器会查看联合中的类型,如果该类型不可替换,那么Optional
类也不会被认为是可替换的,例如std::tuple<int&>
不可替换,Optional<std::tuple<int&>>
在 P2786 中也被认为不可替换,无法获得vector::erase
等操作的优化。
明天的帖子将介绍如何在牺牲constexpr
支持的情况下,在 P2786 下为Optional
获得“可替换性”。同时还提供了相关的参考链接:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。