Skip to content

搞英语 → 看世界

翻译英文优质信息和名人推特

Menu
  • 首页
  • 作者列表
  • 独立博客
  • 专业媒体
  • 名人推特
  • 邮件列表
  • 关于本站
Menu

从 C++ 中的函数返回多个值(C++23 版)

Posted on 2025-05-19

许多编程语言(例如 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++ 程序员可以使他们的代码更易于阅读和维护。

进一步阅读:

将 C++ std::optional 与非平凡对象一起使用时需要小心

原文: https://lemire.me/blog/2025/05/18/returning-several-values-from-a-function-in-c-c23-edition/

本站文章系自动翻译,站长会周期检查,如果有不当内容,请点此留言,非常感谢。
  • Abhinav
  • Abigail Pain
  • Adam Fortuna
  • Alberto Gallego
  • Alex Wlchan
  • Answer.AI
  • Arne Bahlo
  • Ben Carlson
  • Ben Kuhn
  • Bert Hubert
  • Bits about Money
  • Brian Krebs
  • ByteByteGo
  • Chip Huyen
  • Chips and Cheese
  • Christopher Butler
  • Colin Percival
  • Cool Infographics
  • Dan Sinker
  • David Walsh
  • Dmitry Dolzhenko
  • Dustin Curtis
  • Elad Gil
  • Ellie Huxtable
  • Ethan Marcotte
  • Exponential View
  • FAIL Blog
  • Founder Weekly
  • Geoffrey Huntley
  • Geoffrey Litt
  • Greg Mankiw
  • Henrique Dias
  • Hypercritical
  • IEEE Spectrum
  • Investment Talk
  • Jaz
  • Jeff Geerling
  • Jonas Hietala
  • Josh Comeau
  • Lenny Rachitsky
  • Liz Danzico
  • Lou Plummer
  • Luke Wroblewski
  • Matt Baer
  • Matt Stoller
  • Matthias Endler
  • Mert Bulan
  • Mostly metrics
  • News Letter
  • NextDraft
  • Non_Interactive
  • Not Boring
  • One Useful Thing
  • Phil Eaton
  • Product Market Fit
  • Readwise
  • ReedyBear
  • Robert Heaton
  • Ruben Schade
  • Sage Economics
  • Sam Altman
  • Sam Rose
  • selfh.st
  • Shtetl-Optimized
  • Simon schreibt
  • Slashdot
  • Small Good Things
  • Taylor Troesh
  • Telegram Blog
  • The Macro Compass
  • The Pomp Letter
  • thesephist
  • Thinking Deep & Wide
  • Tim Kellogg
  • Understanding AI
  • 英文媒体
  • 英文推特
  • 英文独立博客
©2025 搞英语 → 看世界 | Design: Newspaperly WordPress Theme