C++ 有没有一个建议?运算符/C+的空条件运算符+;?

C++ 有没有一个建议?运算符/C+的空条件运算符+;?,c++,c++20,C++,C++20,Rust有一个?操作符用于无异常的错误传播。当函数返回结果或选项类型时,可以编写: let a = get_a()?; 这实际上意味着: let _a = get_a(); let mut a = match _a { Ok(value) => value, Err(e) => return Err(e), } 或者,换句话说,如果返回的值包含错误,则函数将返回并传播错误。所有这些都发生在一个字符中,因此代码紧凑,没有太多的if(err)return err分支

Rust有一个
操作符用于无异常的错误传播。当函数返回
结果
选项
类型时,可以编写:

let a = get_a()?;
这实际上意味着:

let _a = get_a();
let mut a = match _a {
    Ok(value) => value,
    Err(e) => return Err(e),
}
或者,换句话说,如果返回的值包含错误,则函数将返回并传播错误。所有这些都发生在一个字符中,因此代码紧凑,没有太多的
if(err)return err
分支

C#中也存在同样的概念:

在C++中,我能找到的最接近的是Boo.Relay.但这两个都需要使用e。Glambdas实现了同样的目标,但它没有那么简洁。据我所知,像这样影响控制流需要某种语言特性或扩展


我试图找到一个能够实施它或至少与之相关的提案,但没有成功。有没有一个C++建议来实现它?

,可以通过结合宏、建议和编写宏来实现同样的效果:

#定义TRY(e)inspect(e){\
err=>返回err\
val=>val\
}
这里的困难在于,在Rust中,每个
结果
实例化仍然有
Ok
Err
类型,我们没有一个方便的机制从
std::expected
中提取错误类型


而这一方法的真正实现可能需要对其他类似于
结果的错误处理类型进行一些概括,这些类型可能会以稍微不同的方式暴露错误变量。

没有这样的建议。在不久的将来也不太可能有这样的情况。C++标准库目前甚至没有值或错误类型,所以只有一个操作员的唯一目的是自动拆装这些类型,看起来非常马虎。

目前,C++委员会看起来是这样的,并因此转向了一个Python的环境,在这种环境中,你只使用了这种情况的例外。 为了完整性(没有其他原因),我将提到存在

co_wait
。我之所以提出这个问题,是因为你可以(ab)使用
co_wait
做一些行为上与你想要的相当的事情

在对象上执行
co_wait
时,协程机制将给定表达式转换为最终形式。协同程序机器可以暂停函数的执行,将控制权返回给调用者。这种机制有能力影响函数的返回值。这看起来有点像一个正常的函数返回,如果你眯着眼睛看得够厉害的话

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

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

  • 根据
    co_wait
    的意图,这是没有意义的。协同程序应该是一个暂停执行的函数,以便在某个异步进程完成时恢复执行。也就是说,函数“wait”在某个对象上。但你没有等待任何东西;您正在(ab)使用
    co_wait
    创建转换或返回的效果。因此,阅读代码的人不一定知道发生了什么,因为实际上没有“等待”什么

  • 您的函数将成为一个协同程序,而成为一个协同程序会产生问题。也就是说,由于协同程序预计将恢复,因此它们有一定数量的行李。例如,
    co_return
    不允许保证省略(将来可能无法更改以允许)。每个协同程序都有一个promise对象,它充当内部函数及其返回值之间的中介。协同路由是动态分配的,不动态分配它们被认为是一种优化。因此编译器可能不会优化这种情况。等等

  • 您不能有一个“正常”的协同程序,它也会以这种方式传播错误。函数使用
    co_wait
    表示错误,或使用
    co_wait
    表示实际等待;不能两者兼而有之。因此,如果您想要一个可能失败的协同程序,您必须手动执行


  • C++提出了加速异常的建议,这样它们就可以成为流量控制的有用工具,而不会像当前的异常机制那样有明显的性能损失。目前没有应用于<代码>?>代码的当前标准类型。而
    三元运算符可能有问题…@Jarod42它不是我的,因为它不是一个新概念。这也是我提出这个问题的原因:)我的意思是,在使用新的“宏运算符”(允许有条件地退出当前函数)之前,我认为我们应该首先对
    expected
    或类似内容提出一些建议。异常目前看起来更像是最终语法…Boost.Leaf也是朝着这个方向努力的,但宏正是问题所在。宏现在已经成为可能,我认为Boost使用它。