C++ 中的多返回值的实现
本文将循序渐进的从最古老的C风格开始,一直讲到C++17中多返回值的实现方法
C风格
传入指针
以指针形式传入待返回的值得地址,作为实参,并在类内对其赋值。
经典实现如下
void func(int a, int b, int *c, int *d)
{
// ... do sth with a,b
// 对*c,*d赋值
}
可以看出我们需要以func(a, b, &c, &d)
这样的方式调用func,不仅不方便不直观,而且需要提前定义c, d,代码比较不简洁。而且输入输出不分离,也不大优雅。
返回结构体
经典实现如下
typedef struct{
int c;
int d;
} return_v;
retuen_v void func()
{
// do sth
return return_v{c, d};
}
麻烦就不说了,还污染了命名空间。而且再调用时,还要准备一个变量接受返回值,再从这个仅用一次的变量中取出需要的变量,太麻烦了。
modern c++ 风格
现代c++的多返回值得实现基本上用tuple实现,优雅而简洁。当然和python、go这种语言级的语法糖来说显得还是稍微麻烦一点的。不过有的人相较于语法糖形式的,说不定更喜欢这种学院派的泛型风格也说不定2333。
为什么不用pair
- pair可以完全被tuple取代。
- tuple泛用性更好。
- tuple在之后的c++标准中,有着更为重要的地位。也就是说会有越来越多的语法支持。
c++11 风格
#include <tuple>
std::tuple<int, int> divide(int dividend, int divisor) {
return std::make_tuple(dividend / divisor, dividend % divisor);
}
#include <iostream>
int main() {
using namespace std;
int quotient, remainder;
tie(quotient, remainder) = divide(14, 3);
cout << quotient << ',' << remainder << endl;
}
用tie
来绑定返回值从tuple
。虽然比较方便,但是make_tuple
这种形式还是稍显扭曲。
自从粗读了c++ stl的代码后,我越发觉得stl的作者太厉害了。就像是上文的这种多返回值语法,实现是非常精妙的。在不添加新的语法糖的情况下,在已有的语法框架下,实现了这么复杂的功能。这非常符合我少即是多的想法,而且统一性好多了2333。
c++17风格
warning 您的编译器未必支持这么新的语法
#include <tuple>
std::tuple<int, int> divide(int dividend, int divisor) {
return {dividend / divisor, dividend % divisor};
}
#include <iostream>
int main() {
using namespace std;
auto [quotient, remainder] = divide(14, 3);
cout << quotient << ',' << remainder << endl;
}
用了新的c++特性,绑定结构体,精妙而美丽。
c11/c17混用
当然我们也没必要全部使用c11的特性,或者全用c17的特性。
他们不互相矛盾,可以这样混用
#include <tuple>
std::tuple<int, int> divide(int dividend, int divisor) {
return {dividend / divisor, dividend % divisor};
}
#include <iostream>
int main() {
using namespace std;
tie(quotient, remainder) = divide(14, 3);
cout << quotient << ',' << remainder << endl;
}
缺点
tuple技术没有显示地给出返回值的意义,仅有类型。也就是说你得在注释里给出。
std::tuple<int, int> divide(int dividend, int divisor); // return {quotient, remainder}
warning 如果你的项目中这一点非常重要还是使用结构体法吧。
不过话说真的有人有这个需求吗。。。
License:
CC BY 4.0