许多编程语言(例如 Go 编程语言)都旨在轻松地从函数一次返回多个值。在 Go 中,它通常用于返回可选的错误代码。C++ 编程语言本身并不支持返回多个值。但是,一些标准类型可以实现相同的目的。如果需要返回两个值,可以使用 std::pair 实例。如果需要返回两个或更多值,可以使用 std::tuple 实例。在最新的 C++ 标准中,它运行得非常好!
假设我们想要计算除法,当一个人试图除以零时,会出现一个字符串错误消息:
std :: tuple < int , std :: string >除法( int a , int b ) { 如果( b = = 0 ) { 返回{ 0 , "错误:除以零" } ; } 返回{ a / b , "成功" } ; }
这种方法效果很好。代码清晰易读。
你可能会担心我们修复了类型 (int)。如果你想为所有整数类型编写一个函数,你可以使用如下概念来实现:
#包括<概念> 模板< std :: integral int_type > std :: tuple < int_type , std :: string >除法( int_type a , int_type b ) { 如果( b = = 0 ) { 返回{ 0 , "错误:除以零" } ; } 返回{ a / b , "成功" } ; }
有了这个定义,你可以调用 divide(10,3),但是如果你尝试调用 divide(10.0, 3.1323),你会得到一个错误信息,例如“’double’ 不满足 ‘integral’”。
到目前为止,一切都很好。
在 C++17 之前,没有优雅的方法可以调用此函数并立即捕获值,而无需使用样板代码。幸运的是,我们现在有了结构化绑定:
自动[结果,消息] =除( 10 , 2 ) ; std :: println ( "结果:{},消息:{} " ,结果,消息) ;
作为奖励,在这个例子中,我使用了 C++23 的 std::println 函数,该函数在 GCC 14 和 LLVM 19 中可用。
结构化绑定方法(关键字 ‘auto’ 后跟括号)很好,但是如果您只关心其中一个返回值怎么办?在 C++23 中,您可以使用下划线来表示您不关心该值:
自动[商, _ ] =除( 15 , 3 ) ; std :: println ( "仅商: {} " ,商) ;
如果你已经有变量,并且不想创建新变量,该怎么办?可以使用 std::tie:
std :: string msg = “你好” ; int i = 42 ; std :: tie ( i , msg ) =除( 3,0 ) ;
因此您可以编写合适的错误处理代码:
if ( auto [ res , err ] = divide ( 8 , 0 ) ; err ! = "成功" ) { std :: println ( "发生错误:{} " , err ) ; }别的{ std :: println ( "结果: {} " , res ) ; }
如果返回两个值仅仅是为了返回错误码,那么效果会更好一些。您可以使用 std::expected。
您的除法函数可能写成……
模板< std :: integral int_type > std :: expected < int_type , std :: string >除法( int_type a , int_type b ) { 如果( b = = 0 ) { 返回std :: accidental ( "错误:除以零" ) ; } 返回a / b ; }
它允许您编写稍微简单一点的错误处理代码:
如果(自动res1 =除法( 10,2 ) ) { std :: println ( "结果:{:>4},消息:成功" , res1.value ( ) ) ; }别的{ std :: println ( "错误: {} " , res1 . error ( ) ) ; }
std::expected 的另一个好处是您可以让调用代码选择默认值(在出现错误的情况下):
int商=除法( 15 , 3 ) .值或( 0 ) ; std :: println ( "仅商: {:>4} " ,商) ;
如果您愿意,可以使用 std::optional,其工作方式大致相同:
std ::可选<int>除法( int a , int b ) { 如果( b = = 0 ) { 返回std :: nullopt ; } 返回a / b ; }
然而,std::optional 不太适合错误处理:你不能传递错误代码或错误消息。std::optional 策略适用于可以省略值的简单情况。
在 C++ 中,函数返回多个值的方式已得到显著改进,为开发者提供了灵活而优雅的解决方案。从使用 std::pair 和 std::tuple 实现通用的多值返回,到利用 std::expected 实现强大的错误处理,以及使用 std::optional 实现可选值。通过采用这些技术,C++ 程序员可以使他们的代码更易于阅读和维护。
进一步阅读:
原文: https://lemire.me/blog/2025/05/18/returning-several-values-from-a-function-in-c-c23-edition/