为什么std::nullopt_t是C++标准的一部分?

11
我不理解将 std::nullopt_t 包含在标准中的原因。它存在是为了方便,还是必须在某些特殊情况下使用?
需要澄清的是,我知道它用作构造空的 std::optional 对象的参数。但考虑到已经存在 std::optional 的默认构造函数,似乎没有明显的动机来存在 std::nullopt_tstd::optional 必须存在这样的构造函数和赋值运算符才能符合特定的概念吗?如果是这样的话,是哪个概念?

这是关于 std::optional 的内容。 - NathanOliver
阅读文档应该足以澄清你的任何疑问,不是吗? - Sergey Kalinichenko
抱歉问题描述不够清晰。std::nullopt的预期使用是足够明确的。我的问题围绕相关的std::optional构造函数和赋值运算符的实际必要性。 - Zark Bardoo
3
看起来这主要是出于方便考虑,并且为其提供类指针的行为:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3672.html#rationale.nullopt - NathanOliver
@NathanOliver 我认为那应该是一个答案,尽管需要注意该段落中指出需要消除歧义的情况。嗯,确切地说:这就是答案。 - underscore_d
3个回答

20

nullopt_tnullopt的类型,表示无效的optional状态。 nullopt允许消除重载,例如(来自optional提案的示例):

void run(complex<double> v);
void run(optional<string> v);

run(nullopt);              // pick the second overload
run({});                   // ambiguous

3
使用optional<string>{}会强制重复类型名称。不必重复自己是好的。引入auto变量类型推导背后的原因相同。虽然不是必需的,但它有助于简化代码。 - eerorika
1
@user2079303 你是在暗示使用标准的DRY原则吗? ;) - NathanOliver
3
auto 是‘仅供方便’使用的。‘方便’会增加编写漏洞的难度。我们甚至可以用brainfuck替换整个标准,仍然可以编写完全相同的程序。只是不那么‘方便’了。” - eerorika
1
澄清一下,我并不反对这是为了方便起见,我只是想指出,考虑是否为了方便起见的重点是无意义的。 - eerorika
1
@user2079303 我理解你的观点,但我认为这可能是一种过度简化。例如,std::variant增加了方便性,但我可能会认为像std::monostate这样的类在std::variant添加后是必须存在的。std::optional同样增加了方便性,但它的实现并不像std::variant需要std::monostate那样需要std::nullopt的存在。 - Zark Bardoo
显示剩余2条评论

4

这里是我最近遇到的另一个例子:

// GCC: error: expected primary-expression before '{' token
// Clang: error: initializer list cannot be used on the right hand side of operator ':'
std::optional<int> x = some_condition ? std::optional(0) : {}; 

// works
std::optional<int> y = some_condition ? std::optional(0) : std::nullopt;

0

C++的参考文档已经说明了:

std::nullopt_t是一个空类类型,用于表示未初始化状态的optional类型。特别地,std::optional具有使用nullopt_t作为单个参数的构造函数,该构造函数创建一个不包含值的optional

std::nullopt_t


5
"nullopt"的含义很清晰,但我们不清楚为什么需要它。 - gomons

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接