Outcome 2.2 库
版权所有 © 2014-2025 Niall Douglas 及其他贡献者
根据 Boost 软件许可证 1.0 版分发。(请参阅随附的 LICENSE_1_0.txt 文件或访问 https://boost.ac.cn/LICENSE_1_0.txt 获取副本)
介绍
Outcome 是一套用于在**不适合直接使用 C++ 异常处理**的场景下报告和处理函数失败的工具。此类场景包括:
程序或其部分被编译为禁用异常;
程序部分存在大量依赖于失败类型的分支,此时 `if` 语句比 `try-catch` 块更清晰;
硬性要求执行的失败路径不应比成功的路径成本更高;
存在一些情况,例如在
filesystem库中,失败应远程处理(使用 C++ 异常抛出)还是本地处理无法在函数内部确定,需要由调用者决定,而在后一种情况下,出于上述原因,抛出 C++ 异常并非理想选择;程序/框架的部分内容本身实现了异常处理,并倾向于不使用异常在线程、任务、协程等之间传播失败报告;
需要通过不实现异常抛出安全的层来传播异常;
存在外部要求(如公司范围的政策)要求在代码中明确指示失败处理路径。
在与 C 代码互操作很重要,而无需诉诸 C++ 异常包装器的情况。
您的主要是 C 代码库需要类似异常的错误处理,并且 C 中可用的 Outcome 功能子集已满足您的需求。
Outcome 通过从函数返回一个特殊类型来处理失败,该类型能够存储成功计算的值(或 `void`)或失败信息。Outcome 还附带了一套处理此类类型的惯用法。
特别注意确保 Outcome 对构建时间的影响尽可能小,使其适用于非常大的代码库的全局头文件中。`result
Outcome 对完全确定的、全部 `noexcept` 的 C++ 协程支持尤其强大,我们提供了 Outcome 优化的 eager<T, Executor = void>/atomic_eager<T, Executor = void>、lazy<T, Executor = void>/atomic_lazy<T, Executor = void> 和 generator<T, Executor = void> 协程,它们适用于任何用户类型。
示例用法(C++)
Outcome 库中的主要工作是 `result
outcome::result<string> data_from_file(string_view path) noexcept;
可以手动检查状态
if (outcome::result<string> rslt = data_from_file("config.cfg"))
use_string(rslt.value()); // returns string
else
throw LibError{rslt.error(), "config.cfg"}; // returns error_code
或者,如果此函数在另一个也返回 `result
outcome::result<int> process(const string& content) noexcept;
outcome::result<int> int_from_file(string_view path) noexcept
{
BOOST_OUTCOME_TRY(auto str, data_from_file(path));
// if control gets here data_from_file() has succeeded
return process(str); // decltype(str) == string
}
BOOST_OUTCOME_TRY 是一个控制语句。如果返回的 `result
示例用法(C)
等同于 C++ API:BOOST_OUTCOME_C_DECLARE_RESULT_SYSTEM(ident, T) 声明 C 类型,之后 BOOST_OUTCOME_C_RESULT_SYSTEM(ident) 指代它。您在函数的返回类型中使用它。
BOOST_OUTCOME_C_DECLARE_RESULT_SYSTEM(result_string, const char *)
BOOST_OUTCOME_C_RESULT_SYSTEM(result_string) data_from_file(const char *path);
可以手动检查状态
BOOST_OUTCOME_C_RESULT_SYSTEM(result_string) rslt = data_from_file("config.cfg");
if(BOOST_OUTCOME_C_RESULT_HAS_VALUE(rslt))
use_string(rslt.value); // returns string
else
fprintf(stderr, "%s\n", outcome_status_code_message(&rslt.error));
或者,如果此函数在另一个也返回 BOOST_OUTCOME_C_RESULT_SYSTEM(ident) 的函数中调用,您可以使用专门的控制语句。
BOOST_OUTCOME_C_DECLARE_RESULT_SYSTEM(result_int, int)
BOOST_OUTCOME_C_RESULT_SYSTEM(result_int) process(const char *content);
BOOST_OUTCOME_C_RESULT_SYSTEM(result_int) int_from_file(const char *path)
{
BOOST_OUTCOME_C_RESULT_SYSTEM_TRY(const char *str, result_int, /* cleanup on fail */, data_from_file(path));
// if control gets here data_from_file() has succeeded
return process(str); // decltype(str) == string
}
C Result 的布局保证与其 C++ 等效项完全相同。提供了方便的转换函数,但您也可以使用 `reinterpret_cast`。


