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

问题描述 投票:0回答:1

在最受尊敬的 stackoverflow 答案之一中,我找到了

std::expected
模板类用法的示例: C++20 中的协程是什么?

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

c++ error-handling c++-faq c++23 std-expected
1个回答
64
投票

实际上,了解

std::expected
的最佳方式是著名的 Andrei Alexandrescu 的有趣演讲:“期待所期待的!”

什么是
std::expected
以及何时使用

以下是关于

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);
    
  • 它是

    T
    E
    类型的可区分联合,并带有一些便捷方法。

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

它的行为有点像

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

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

实际上,如果我们遇到错误,最后一种访问模式的行为与

std::optional
不同:它抛出的是
bad_expected_access<E>
,并返回错误。这种行为可以被认为是从基于预期的错误处理切换到基于异常的错误处理的一种方法。

“嘿,我在标准中查找了它,但没有!”

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

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

  • 我可以推荐 Sy Brand (tartanllama) 的 implementation,它可以与 C++11 或更高版本一起使用。它还具有一些简洁的函数式扩展(可能未标准化)。
  • @Malachi 推荐 estd::expected,这是用于嵌入式环境的标准库实现的一部分。
© www.soinside.com 2019 - 2024. All rights reserved.