std::nullopt_t 构造函数原理

Ziz*_*Tai 4 c++ c++11 c++14 c++17

本页所述

std::nullopt_t必须是 aLiteralType并且不能有默认构造函数。它必须有一个constexpr构造函数,该构造函数采用某种实现定义的文字类型。...注释 nullopt_tDefaultConstructible支持op = {};op = nullopt;作为脱离可选对象的语法。

...而且,一个可能的实现是

struct nullopt_t {
    constexpr nullopt_t(int) {}
};
Run Code Online (Sandbox Code Playgroud)

实际上,在阅读本文后,我不太明白其背后的原理。

(1) 为什么nullopt_t不做DefaultConstructible?我不太明白“......支持两者......”部分。

(2) 为什么可能的构造函数采用int,而boost::none_t采用空类型boost::none_t::init_tag?这两种实现有何不同?

T.C*_*.C. 5

为什么nullopt_t不做DefaultConstructible

cppreference 需要一个小的修复。“not DefaultConstructible”不是对预期语义的正确描述。1

在任何情况下,目的是给定operator=(optional&&)and operator=(nullopt_t)opt = {}将明确地转到第一个,而不是引起歧义,这是通过使 无法构造nullopt_tfrom 来实现的{}。请注意,“分配值”operator=是一个模板,因此也= {}无法使用。

为什么可能的 ctor 会采用int,而boost::none_t采用空类型boost::none_t::init_tag?这两种实现有何不同?

该标准未指定如何nullopt_t构造 a 。(你应该使用nullopt。)所以一般你只需要添加一个构造函数取东西,而忽略它。具体是什么取决于实施者。


1以下病理实现满足当前工作草案中的所有要求,不是DefaultConstructible,但仍然中断opt = {}

struct nullopt_t {
    constexpr nullopt_t(const nullopt_t&) = default;
};

constexpr nullopt_t nullopt(nullopt_t{});
Run Code Online (Sandbox Code Playgroud)

  • @NicolBolas 要成为`DefaultConstructible`,你必须满足*所有* 的要求,但要不是`DefaultConstructible`,你只需要破坏其中的*一个*(例如,`T()` 工作)。 (2认同)