有提案吗?C++ 的运算符/空条件运算符?

Vla*_*nov 3 c++ c++20

Rust 有一个?用于错误传播的运算符,无一例外。当函数返回ResultorOption类型时,可以这样写:

let a = get_a()?;
Run Code Online (Sandbox Code Playgroud)

这实际上意味着:

let _a = get_a();
let mut a = match _a {
    Ok(value) => value,
    Err(e) => return Err(e),
}
Run Code Online (Sandbox Code Playgroud)

或者,换句话说,如果返回值包含错误,该函数将返回并传播错误。所有这些都发生在一个字符中,因此代码很紧凑,没有太多if (err) return err分支。

C# 中也存在相同的概念:空条件运算符

在 C++ 中,我能找到的最接近的东西是tl::expected和 Boost.outcome。但这两个需要使用例如 lambda 来实现相同的目标,并且它不那么简洁。据我了解,影响这样的控制流需要某种语言功能或扩展。

我试图找到一个能够实现它或至少与之相关的提案,但没有找到。是否有实现它的 C++ 提案?

Nic*_*las 5

没有这样的提议。在不久的将来也不可能出现这样的情况。C++ 标准库目前甚至没有值或错误类型,因此拥有一个其唯一目的是自动解包此类类型的运算符似乎非常本末倒置。

目前,C++ 委员会似乎更感兴趣的是找到一种方法来使异常抛出更便宜,从而转向类似 Python 的环境,在该环境中您只需使用异常来处理此类事情。

为了完整起见(没有其他原因),我将提及它的co_await存在。我提出这个问题是因为你可以(滥用)co_await做一些与你想要的行为等效的事情。

当您co_await使用一个对象时,协程机制会将给定的表达式转换为其最终形式。协程机制可以暂停函数的执行,将控制权返回给调用者。并且这种机制有能力影响函数的返回值。如果你仔细观察的话,这看起来有点像一个普通的函数return 。

考虑到所有这些,您可以(ab)将协程机制用于返回值或错误类型(例如expected. 您可以co_await使用某些值或错误类型。如果表达式是一个值,则co_await不会挂起该函数,并且将从表达式中解压该值。如果表达式有错误,则将co_await“挂起”该函数并将错误值传播到该函数的返回值中。但在“挂起”它时,协程机制实际上永远不会安排协程的执行恢复,因此一旦控制权交还给调用者,协程就会终止。

话虽如此,你永远不应该这样做。不全面的原因列表如下:

  1. 根据打算做什么,这是没有co_await意义。协程应该是一个暂停执行的函数,以便在某个异步进程完成时恢复它。也就是说,函数“等待”某件事。但你并不是在等待任何事情;而是在等待。您正在(ab)使用它co_await来创建变换或返回的效果。因此,阅读代码的人不一定知道发生了什么,因为实际上没有任何内容被“等待”。

  2. 你的函数变成了一个协程,而作为一个协程会产生问题。也就是说,因为协程预计会恢复,所以它们有一定的包袱。例如,co_return不允许保证省略(并且将来可能无法更改以允许它)每个协程都有一个 Promise 对象,充当内部函数及其返回值之间的中介。协程是动态分配的,不动态分配也被认为是一种优化。所以编译器可能不会优化这种情况。等等。

  3. 您不可能有一个“正常”协程以这种方式传播错误。函数要么用于co_await错误,要么用于co_await实际等待;它不能两者兼而有之。因此,如果您想要一个可能失败的协程,则必须手动执行操作。