从函数返回值:引用vs结构

Returning values from a function : reference vs struct

本文关键字:vs 结构 引用 函数 返回值      更新时间:2023-10-16

我是一个编程新手,我正在使用《c++编程原理和实践》这本书学习c++编程语言。我今天在这里是因为在第8章的末尾,作者重点介绍了函数,并提出了一个练习,邀请学习者思考问题的更好解决方案:

编写一个函数,查找vector参数的最小和最大元素,并计算平均值和中位数。不要使用全局变量。要么返回包含结果的struct,要么通过引用参数将它们传递回去。这两种方法中,你更喜欢哪一个,为什么?

现在,通常我不会定义一个函数来执行几个操作,但在这种情况下,我必须创建一个函数,并考虑如何返回几个值。我的第一种方法是创建一个函数,它接受像这样的引用参数:

void my_func(
    vector<double>& numbers,
    double& min,
    double& max,
    double& mean,
    double& median
);

但是继续编写程序,我开始认为这个解决方案使用了太多的参数,也许提出的另一个解决方案(使用struct)会更好。你会如何使用struct来解决这个问题?你如何从一个函数返回几个值?

使用struct解决这个问题很简单:为返回类型定义一个struct,并像这样使用它:

struct stats {
    double min;
    double max;
    double mean;
    double median;
};
stats my_func(vector<double>& numbers) {
    stats res;
    ...
    res.min = ...
    res.max = ...
    res.mean = ...
    res.median = ...
    return res;
}

这里的权衡是,为了获得更简单的函数签名,函数的用户需要一个接一个地提取他们想要的元素。

但是,如果结构体非常复杂,并且复制的成本变得非常昂贵怎么办?

与函数的"有效负载"CPU时间相比,它需要一个非常大的结构来进行复制,从而变得过于昂贵。最重要的是,c++优化器通过使用复制省略和返回值优化策略来减少复制成本:

stats s = my_func(numbers);

struct变得如此巨大以至于你不想复制它时,将这两种方法结合起来,像这样:

void my_func(vector<double>& numbers, stats& res);

声明struct

struct stats {
   double min;
   double max;
   double mean;
   double median;
};
然后

stats my_func(vector<double>& numbers);

函数将是这样的

stats my_func(vector<double>& numbers) {
    stats return_value;
     // Fill in the structure
    return return_value;
}

你只是返回一个结构体。

struct res {
   double min; 
   double max;
   double mean;
   double median;
};
res my_func(vector<double>& numbers) {
    res result;
    // do stuff, put result in in result.min etc
    return result;
}

另一个可以用类似的方式完成:

void my_func(vector<double>& numbers,
             res& result)
{
    // the same code except no return value
    return;
}

现在,对于你的任务中的问题(我不会回答,因为这是一个你喜欢的问题),我想提一下技术上的区别是什么。

当返回一个结构体时,这意味着您可能会创建result结构体的临时副本(它也可能导致两个对象res,一个用于调用者,一个用于my_func)。而另一种方法意味着您传递给函数的本质上是解决放置结果的位置。使用"好的"实现,您可能最终得到相同的代码。