6

在最受尊敬的 stackoverflow 答案之一中,我找到了一个std::expected模板类用法示例: C++20 中的协程是什么?

同时,我在 cppreference.com 上找不到任何关于此类的提及。你能解释一下它是什么吗?

4

1 回答 1

11

实际上,最好的学习方法std::expected是(不知名的)安德烈亚历山德雷斯库的一次有趣的演讲:“期待预期!”

它是什么以及何时使用

以下是对 an 是什么的三个补充解释std::expected<T, E>

  • 它是应该返回T值的函数的返回类型 - 但可能会遇到一些错误,在这种情况下,它将返回该错误的描述符,类型为E。例子:

    std::expected<ParsedData, ParsingError> parse_input(Input input_);
    
  • 这是一种错误处理机制,可以替代抛出异常(在这种情况下,您总是返回您应该返回的值)和返回状态/错误代码(在这种情况下,您永远不会返回您想要的值,并且有使用外参数)。以下是应用于先前定义中的函数的两种替代错误处理机制:

    ParsedData    parse_input_2(Input input) noexcept(false);
    ParsingError  parse_input_3(ParsedData& result, Input input);
    
  • 它是有区别的类型联合TE一些方便的方法。

“它怎么比一个更好std::variant<T,E>?”

它的行为有点像std::optional<T>,将重点放在预期的而不是意外的情况上:

  • result.has_value()- 如果我们得到一个值而不是错误,则为 true。
  • if (result)- 检查相同的东西
  • *result-T如果存在,则为我们提供值,否则为未定义的行为(与 相同std::optional,尽管许多人不喜欢这样)。
  • result.value(), 如果它存在则给我们T值,否则抛出。

实际上,最后一种访问模式的行为与std::optional我们遇到错误时的行为不同:它抛出的是 a bad_expected_access<E>,并返回错误。这种行为可以被认为是从基于预期的错误处理切换到基于异常的错误处理的一种方式。

“咦,我在标准里找了,没有!”

没错,在撰写本文时,std::expected这是一个用词不当。尚未标准化,仅提出:P0323。看起来它可能会进入 C++23。

话虽这么说 - 它已经非常有用了,因为它不需要新的语言设施。我会推荐 Sy Brand (tartanllama) 的implementation,它可以与 C++11 或更高版本一起使用。它还有一些简洁的函数式扩展(可能不是标准化的)。

于 2022-01-03T20:50:05.547 回答