【问题标题】:Implementation of the std::optional classstd::optional 类的实现
【发布时间】:2014-11-08 18:37:38
【问题描述】:

我需要为可选值实施快速解决方案。我不想拖入任何第三方库。

可选类一般是如何实现的?当一个可选对象处于“空状态”时,它是否仍然默认构造底层对象?

【问题讨论】:

  • 你研究过Boost.Optional的实现吗?
  • C++ 标准库不是第三方库。我想你还不想开始使用 C++14?
  • @E_net4 我的编译器还不支持。
  • 剪切/粘贴 boost::optional
  • 基本上来说,Boost.Optional(正如 Angew 所建议的)最终被接受为 std::optional。因此,如果您背负着旧(er)编译器的负担,那么 Boost.Optional 就是您要走的路。 (类似于 Boost.smart_ptr 和 std::shared_ptr。)我理解对第三方库的不情愿,但没有 Boost 的 C++ 势必会重新发明久经考验的轮子。

标签: c++


【解决方案1】:

可选类一般是如何实现的?

通常,一个布尔标志来指示它是否为空,以及一个适当大小和对齐的字节数组来存储值。

当一个可选对象处于“空状态”时,它是否仍然默认构造底层对象?

没有;这将对存储类型施加不必要的要求,并导致潜在的不良副作用。当optional 变为非空时,将使用placement-new 创建存储的对象,并在变为空时使用析构函数调用销毁。

对于快速而简单的实现,如果您不需要 Boost 或建议的标准版本的所有灵活性,您可以简单地存储一个默认构造的对象。

我不想拖入任何第三方库。

我会重新考虑为什么你不觉得你想要那个。 Boost 实现仅是标头,经过良好测试,并且应该在标准版本到来时直接替换为标准版本。我当然更相信它,而不是我自己拼凑的东西。

【讨论】:

    【解决方案2】:

    首先,我强烈建议您查看 Boost(特别是 Boost.Optional) - 使用 Boost 几乎是标准做法,它可以避免您重新发明轮子。

    如果由于某种原因你不愿意使用 Boost.Optional,有一堆类似的纯头文件库,例如 https://github.com/akrzemi1/Optional

    【讨论】:

      【解决方案3】:

      或更早版本中,您可以使用经过空值检查的T* 或仅使用std::pair<T, bool>。后者的问题是,如果您的默认构造 T 很昂贵,那可能是一种浪费。

      或更高版本中,您仍然可以使用T*,但您也可以使用std::optional<T>。这里后者只在有效的情况下构造一个T

      值得注意的是,std::optional 仅在少数情况下是一个不错的选择:https://topanswers.xyz/cplusplus?q=923#a1085

      【讨论】:

      • 我不同意 std::optional<T> 仅在少数情况下是一个不错的选择。使用std::optional<T> 而不是T* 的意义在于std::optional<T> 直接包含T,因此您不需要额外的间接层来表示拥有的可能不存在的值。
      • 我同意 cuddlebugCuller 的观点。更重要的是,接口比一个稀有的指针清晰得多,它没有说明它是否可以为nullptr
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-05
      • 2019-02-19
      • 1970-01-01
      • 2018-06-07
      • 1970-01-01
      • 2021-02-06
      • 1970-01-01
      相关资源
      最近更新 更多