Cherno C++学习笔记 P52 处理多返回值

devtools/2025/1/15 14:52:39/

在这篇文章当中,我们解决一下如何用C++的函数处理多返回值的问题。

在有些情况下,我们希望我们的函数可以返回多个返回值,比如返回两个string或者是一个int加上一个string。如果我们用的是python之类的语言的话,那这个事情其实是很好实现的。但是因为我们用的是C++,而C++本身是不支持我们一个函数返回两个类型的变量的。当然如果是一个类型的话,那确实容易一些,我们可以使用array/vector这些容器来装下这多个同类型的变量,比如这里我们举一个简单的例子,返回多个我们定义的Vertex类型组成的vector:

#include<iostream>
#include<string>
#include<vector>struct Vertex {
public:float x, y, z;
public:Vertex(float x, float y, float z):x(x), y(y), z(z){}
};static std::vector<Vertex> function() {Vertex v1(2.0f, 1.0f, 0.5f);Vertex v2(-2.0f, 1.6f, 0.7f);std::vector<Vertex> vertices{ v1, v2 };return vertices;
}

当然,实际上我们也可以使用静态数组array,但是因为array建立在栈上,而vertex是建立在堆上,所以严格来说,使用array性能会更好一些。 

但是如果我们想要返回两个类型,比如一个int和一个Vertex这类的话,我们应该怎么做?一种解决办法是,讲两种类型放入到一个struct当中,然后我们的函数返回这个struct:

struct Vertex {
public:float x, y, z;
public:Vertex(float x, float y, float z):x(x), y(y), z(z){}
};struct Combine {
public:int dimension;Vertex v;
public:Combine(int a, Vertex v):dimension(a), v(v){}
};static Combine function() {int d = 3;Vertex v(2.0f, 1.0f, 0.9f);Combine rtn(d, v);return rtn;
}

我们可以看到,这样我们就做到了返回两个类型的变量组成的结构体,达到了我们想要返回多个变量的目的。这也是Cherno自己最喜欢的方法。

除了这个方法之外,还可以用另一个方法,这个也是很多实践场合会使用的办法,就是把函数改成void,然后输入变量改成引用,这样我们就可以用修改引用的方法修改外面已经定义好的量,这样就实现了我们函数修改变量的功能。

static void function(int& dimen, Vertex& vertex) {int d = 3;Vertex v(2.0f, 1.0f, 0.9f);dimen = d;vertex = v;
}

这样的话我们的变量的内存是预分配的,而不需要在函数内部分配。从技术上来讲,这有可能是最理想的方式,因为没有复制发生,我们直接修改了在函数外面的变量,所以其实是可以最快的。同样的,这也是一种输出不同类型变量的风格,在给变量起名字的时候,我们可以给预计要输出的变量添加一个out前缀,来表明这些其实是我们这个函数的输出变量。

当然除了引用之外,我们还可以给函数输入指针,来达到类似的效果。不过区别在于,在使用指针的时候,我们可以通过给一个nullptr来表示我们不想返回这个变量,但是引用却必须要引用某一个变量才能返回。

那么C++有没有给我们一些容器可以让我们塞入不同类型的数据呢?也是有的,那就是tuple,可以让我们放入不同类型的数据,使用方法如下:

static std::tuple<int, Vertex> function() {int d = 3;Vertex v(2.0f, 1.0f, 0.9f);std::tuple<int, Vertex> t(d, v);return t;
}

但是这个其实是非常讨厌的,因为当我们想要获取里面的数值的时候,会发现非常的麻烦:

auto t = function();
std::cout << std::get<0>(t) << std::endl;

我们不得不使用这种方式,那么什么是0?什么是1?它们具体指代的是什么?这个其实是很混淆的,我们是不知道的。这就会大大降低我们代码的可读性。

另一个可以采用的是pair,使用方法如下:

static std::pair<int, Vertex> function() {int d = 3;Vertex v(2.0f, 1.0f, 0.9f);auto p = std::pair<int, Vertex>(d, v);return p;
}
auto p = function();
std::cout << p.first << std::endl;

我们可以看到我们能使用first和second这样的字眼,相对好一点,但是好的不多。而在我们使用struct的时候,我们处理的是名字而不是数字或者first之类的,所以采用struct确实是更好的方法。


http://www.ppmy.cn/devtools/150704.html

相关文章

【论文阅读+复现】High-fidelity Person-centric Subject-to-Image Synthesis

以人物为中心的主体到图像的高保真合成&#xff0c;CVPR2024 code&#xff1a;CodeGoat24/Face-diffuser: [CVPR2024] Official implementation of High-fidelity Person-centric Subject-to-Image Synthesis. paper&#xff1a;2311.10329 背景 研究问题&#xff1a;这篇文…

Kylin: `GLIBC_2.34‘ not found

需要查看服务器GLIBC版本 strings /lib64/libc.so.6 |grep GLIBC_如果没有&#xff0c;有两种办法&#xff0c;一种是libc.so.6降级&#xff0c;但是这样很容易将服务器搞崩溃 所以可以尝试下载对应版本 glibc 打包编译&#xff0c;重新建立软连&#xff0c;下列是RPM资源可以…

win10安装anaconda环境与opencv

1 下载anaconda 从清华镜像源下载&#xff0c;下载地址Anaconda3-2024.06-1-Windows-x86_64.exe 。 2 安装anaconda 双击下载的应用&#xff0c;点击下一步&#xff0c;选择一个安装路径&#xff0c;如下所示&#xff0c;然后再点选"Add Anaconda3 to my Path"&am…

空指针:HttpSession异常,SpringBoot集成WebSocket

异常可能性&#xff1a; 404 &#xff1a; 请检查拦截器是否将请求拦截WebSocket握手期间HttpSession为空 HttpSession为空 方法一 &#xff1a; 网上参考大量的文档&#xff0c;有说跟前端请求域名有关系的。 反正对我来说&#xff0c;没啥用无法连接。 需使用 localhost&a…

蓝牙开发 基础知识

文章目录 前言一、蓝牙广播1&#xff1a;广播信道2&#xff1a;广播的数据结构3&#xff1a;用户广播结构4&#xff1a;广播包的内容&#xff1a;广播事件: 二、蓝牙状态切换蓝牙从机&#xff08;Peripheral&#xff09;的状态蓝牙主机&#xff08;Central&#xff09;的状态 三…

ucharts写的小程序如何解决Y轴小数点问题

去除小数点 在yAxis的data中添加 formatter: (value) > { // console.log("formatter", value, typeof (value)) return value > 0 ? Math.floor(value) : value; } yAxis: {gridType: "dash",dashLength: 2,data: [{unit: &qu…

scala概念

val声明变量和var声明变量的不同&#xff1f; val修饰不可变变量&#xff0c;var修饰可变变量 trait与class的相同点和不同点&#xff1f; 它们的相同点在于都能包含抽象和非抽象成员&#xff0c;且不能直接实例化。 区别在于抽象类的构造方法可传参&#xff0c;而特质的构…

【2025最新】机器学习类计算机毕设选题80套,适合大数据,人工智能

【2025最新】机器学习类型计算机毕设选题 1-10套 基于Spring Boot的物流管理系统的设计与实现 基于机器学习的虚假招聘信息的分析与预测 基于机器学习的影响数据科学家职业变动因素的分析与预测 基于Spring Boot的历史文物交流平台的设计与实现 基于机器学习的肥胖影响因素的分…