【问题标题】:trivially default constructible std::optional and std::variant平凡的默认构造 std::optional 和 std::variant
【发布时间】:2023-03-15 07:56:01
【问题描述】:

是否允许以这样的方式设计std::optional(当前为std::experimental::optional),即对于普通默认可构造类型T,对应的std::optional< T >也是普通默认可构造类型?

关于std::variant 及其积分鉴别器的相同问题。

我自己的回答是:“不,不能这样设计,因为如果对象有自动存储持续时间或者是reinterpret_cast-ed from non - 零初始化存储。”我不允许要求用户每次都进行值初始化。

【问题讨论】:

  • 我可以问你为什么它对你很重要吗?我可以想象为什么您可以选择简单地复制。但是为什么可以简单地默认构造呢?它能给你带来什么?
  • @Andrzej 容器(如optionalvariant)应该尽可能通用,不是吗?我尝试设计variant for constexpr。并且目前具备以上能力。但我认为“也许我应该否认它?”。
  • @Andrzej 最终我在variant 中发现了一个“错误”。默认初始化对象在编译时(constexpr)和运行时具有不同的行为。然后我读到了intiializations。并发现,有 UB 在堆栈上使用我的默认初始化 variant

标签: c++ c++11 c++14 optional variant


【解决方案1】:

你的答案是正确的:你不能。规范要求其“初始化标志”在默认构造时设置为false

【讨论】:

    【解决方案2】:

    正如你自己解释的那样,你不能以这种方式实现 std::optional,因为你会改变它的语义(is_trivially_default_constructible 是类接口的一部分)。

    但是,如果您出于某种原因在代码中需要这种语义,那么您没有理由不能实现一个非常相似的、默认可构造的可选类。然后,在使用时,只需通过 {} 将其初始化为零,并且 - 如果这是您想要的 - 在 bool 运算符中将零视为 true。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-16
      • 2017-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-27
      • 1970-01-01
      • 2021-11-29
      相关资源
      最近更新 更多