std::nullopt_t 构造原理
std::nullopt_t constructor rationale
如 this page、
所述
std::nullopt_t
must be a LiteralType
and cannot have a default constructor. It must have a constexpr
constructor that takes some implementation-defined literal type. ... Notes nullopt_t
is not DefaultConstructible
to support both op = {};
and op = nullopt;
as the syntax for disengaging an optional object.
...并且,一个可能的实现是
struct nullopt_t {
constexpr nullopt_t(int) {}
};
其实看完后我不太明白背后的道理。
(1) 为什么要nullopt_t
而不是DefaultConstructible
?我不太明白“...支持两者...”部分。
(2) 为什么可能的构造函数采用 int
,而 boost::none_t
采用空类型 boost::none_t::init_tag
?这两种实现方式有何不同?
Why make nullopt_t
not DefaultConstructible
?
cppreference 需要一个小的修复。 "not DefaultConstructible
" 不是预期语义的正确描述。1
无论如何,目的是给定 operator=(optional&&)
和 operator=(nullopt_t)
,opt = {}
将明确地转到第一个,而不是引起歧义,这是通过使得无法从 {}
构建 nullopt_t
。请注意 "assign a value" operator=
是一个模板,因此对于 = {}
也是不可行的。
Why would a possible ctor takes an int
, while boost::none_t
takes an empty type boost::none_t::init_tag
? How do these two implementations differ?
标准未指定如何构造 nullopt_t
。 (你应该使用 nullopt
。)所以通常你只是添加一个构造函数接受 something 并忽略它。 something 究竟是什么取决于实施者。
1下面的病态实现满足了当前工作稿中的所有要求,不是DefaultConstructible
,但还是打破了opt = {}
:
struct nullopt_t {
constexpr nullopt_t(const nullopt_t&) = default;
};
constexpr nullopt_t nullopt(nullopt_t{});
如 this page、
所述
std::nullopt_t
must be aLiteralType
and cannot have a default constructor. It must have aconstexpr
constructor that takes some implementation-defined literal type. ... Notesnullopt_t
is notDefaultConstructible
to support bothop = {};
andop = nullopt;
as the syntax for disengaging an optional object.
...并且,一个可能的实现是
struct nullopt_t {
constexpr nullopt_t(int) {}
};
其实看完后我不太明白背后的道理。
(1) 为什么要nullopt_t
而不是DefaultConstructible
?我不太明白“...支持两者...”部分。
(2) 为什么可能的构造函数采用 int
,而 boost::none_t
采用空类型 boost::none_t::init_tag
?这两种实现方式有何不同?
Why make
nullopt_t
notDefaultConstructible
?
cppreference 需要一个小的修复。 "not DefaultConstructible
" 不是预期语义的正确描述。1
无论如何,目的是给定 operator=(optional&&)
和 operator=(nullopt_t)
,opt = {}
将明确地转到第一个,而不是引起歧义,这是通过使得无法从 {}
构建 nullopt_t
。请注意 "assign a value" operator=
是一个模板,因此对于 = {}
也是不可行的。
Why would a possible ctor takes an
int
, whileboost::none_t
takes an empty typeboost::none_t::init_tag
? How do these two implementations differ?
标准未指定如何构造 nullopt_t
。 (你应该使用 nullopt
。)所以通常你只是添加一个构造函数接受 something 并忽略它。 something 究竟是什么取决于实施者。
1下面的病态实现满足了当前工作稿中的所有要求,不是DefaultConstructible
,但还是打破了opt = {}
:
struct nullopt_t {
constexpr nullopt_t(const nullopt_t&) = default;
};
constexpr nullopt_t nullopt(nullopt_t{});