常量表达式可选且简单的重定位

这是一个简单的 C++20 兼容constexprOptional类型:

  • 包含构造函数、移动构造函数、拷贝构造函数、赋值运算符重载、交换函数和析构函数等。
  • 行为类似于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的可简单移动性,例如对于PolyHolder的组合,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获得“可替换性”。同时还提供了相关的参考链接:

阅读 15
0 条评论