C++ 中的 std::expected 是什么?

What is std::expected in C++?

提问人:Fedor 提问时间:7/14/2021 最后编辑:nachiketkulkFedor 更新时间:5/25/2023 访问量:21376

问:

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

同时,我在 cppreference.com 上找不到任何提及这门课的内容。你能解释一下它是什么吗?

C 错误处理 ++-FAQ C ++23 标准-预期

评论

6赞 Ted Lyngmo 7/14/2021
这是一个幻想 - 可能不会发生 - 但是..可能仍然
6赞 Sergey Kolesnik 7/14/2021
您无法在 cppreference 上找到它,因为它不是标准的一部分
3赞 StoryTeller - Unslander Monica 7/14/2021
这仍然只是一个提案 wg21.link/p0323——无论是否尊重答案,每个人都将自己的意见注入答案中,无论是明示的还是隐含的。在这种情况下,应该(并且将很快)标准化的意见。std::expected
1赞 Ranoiaetep 7/14/2021
就像其他人提到的那样,只是被提议。但是您可以查找一些用户编写的内容: github.com/TartanLlama/expectedexpected
2赞 7/20/2021
en.cppreference.com/w/cpp/error/unexpected

答:

59赞 einpoklum 1/4/2022 #1

实际上,了解 std::expected 的最好方法是著名的 Andrei Alexandrescu 的有趣演讲:“期待预期!

什么是,何时使用std::expected

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

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

    举个例子:

    std::expected<ParsedData, ParsingError> parse_input(Input input);
    
  • 它是一种错误处理机制,是抛出异常(在这种情况下,您始终返回应该返回的值)和返回状态/错误代码(在这种情况下,您永远不会返回所需的值,并且必须使用 out-parameter)的替代方法。

    下面是应用于上一示例中函数的两种替代错误处理机制:

    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- 如果它存在,则给我们值,否则为未定义的行为(与 相同,尽管许多人不喜欢这样)。Tstd::optional
  • result.value(),如果存在,则为我们提供值,否则则抛出。T

实际上,最后一种访问模式的行为与我们收到错误时的行为不同:它抛出的是 ,返回错误。可以将此行为视为从基于预期的错误处理切换到基于异常的错误处理的一种方式。std::optionalbad_expected_access<E>

“嘿,我在标准中找过它,但它不存在!”

std::expected将成为即将推出的 C++23 标准的一部分。该提案(P0323)最近已被接受。

话虽如此 - 它已经非常可用了,因为它不需要新的语言设施:

  • 我可以推荐一个Sy Brand(tartanllama)的实现,它可以与C++11或更高版本一起使用。它还具有一些简洁的功能样式扩展(可能未标准化)。
  • @Malachi 推荐 estd::expected,它是用于嵌入式环境的标准库实现的一部分。

评论

1赞 einpoklum 5/25/2023
@Malachi:将其添加为一个选项,如果您愿意,可以随意编辑以改写。