6

std::optional可以使用类似于普通指针的语法访问其值,例如 .

std::optional<string> some_str;
if (some_str)
    (*some_str).c_str();

但它也有两个功能,has_value()提供value()对其值的访问以及检查该值是否存在。

std::optional<string> some_str;
if (some_str.has_value())
    some_str.value().c_str();

我想知道这两者有什么区别是为了?
1. 更冗长
2. 性能?
3. 更好的日志记录和调试?value()会抛出异常。

4

2 回答 2

10

这里有两个不同的东西。

首先,explicit operator bool() constbool has_value() const. 这些正是同义词。它们的意思完全相同。使用您喜欢的任何一个。

其次,T& value()T& operator*(). 这与vector::atvs.vector::operator[]相同。前者没有先决条件 - 它检查并抛出 - 后者有先决条件 - 如果禁用可选项,则它是未定义的行为。

于 2019-05-10T18:03:02.877 回答
5

std::optional(没有实验性,C++17 在我们身上)定义了两个不同的接口来访问它的可选成员:检查访问 ( std::optional::value) 和未检查访问 ( operator*)。

使用检查访问有两个潜在的缺点 - 首先,由于执行了分支,它会减慢执行速度,其次,如果 value 不存在,它将抛出异常,这在控制流方面可能是不可取的。虽然第二个问题可以通过在调用 value 之前显式检查 value present ( std::optional::has_value) 来缓解,但运行时性能成本仍然存在。

未经检查的访问没有与之相关的性能成本,但只有在您通过其他方式知道该值存在时才能安全使用(即您之前检查has_value过)。否则,程序的行为是未定义的,我们不希望这样。

从上面可以看出,您显示的第二个片段是多余的:

if (some_str.has_value())
    some_str.value().c_str();

检查值是否存在两次(至少在语义上,编译器可能能够优化第二次检查)。不过,更清晰的代码将是

if (some_str.has_value())
    some_str->c_str();
于 2019-05-10T18:02:38.607 回答