从c++函数中返回多个值的首选方法是什么?例如,假设有一个函数对两个整数进行除法并同时返回商和余数。我经常看到的一种方法是使用引用形参:

void divide(int dividend, int divisor, int& quotient, int& remainder);

一种变体是返回一个值,并通过引用形参传递另一个值:

int divide(int dividend, int divisor, int& remainder);

另一种方法是声明一个结构体来包含所有的结果并返回:

struct divide_result {
    int quotient;
    int remainder;
};

divide_result divide(int dividend, int divisor);

这些方法中是否有一种通常是首选的,还是有其他的建议?

编辑:在实际代码中,可能会有两个以上的结果。它们也可能是不同类型的。


当前回答

替代方案包括数组、生成器和控制反转,但在这里不适用。

有些(例如微软在历史上的Win32)倾向于使用引用参数来简化,因为它很清楚由谁分配以及它在堆栈上的外观,减少了结构的扩散,并允许成功的单独返回值。

“纯”程序员更喜欢结构体,假设它是函数值(就像这里的情况一样),而不是函数偶然接触的东西。如果您有一个更复杂的过程,或者带有状态的东西,您可能会使用引用(假设您有不使用类的理由)。

其他回答

我想说,没有首选方法,这完全取决于你将如何处理响应。如果结果将在进一步处理中一起使用,那么结构是有意义的,如果不是,我倾向于将then作为单独的引用传递,除非函数将用于复合语句中:

X =除(X, y, z) +除(a, b, c);

我经常选择在参数列表中通过引用传递“结构”,而不是通过返回新结构的拷贝开销(但这是汗流浃背的小事)。

无效除(整数被除数,整数除数,答案和ans)

我们的参数令人困惑吗?作为引用发送的形参表明值将发生变化(与const引用相反)。合理的命名也可以消除混淆。

在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;
}

c++ 17:

#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;
}

或者使用结构体:

auto divide(int dividend, int divisor) {
    struct result {int quotient; int remainder;};
    return result {dividend / divisor, dividend % divisor};
}

#include <iostream>

int main() {
    using namespace std;

    auto result = divide(14, 3);

    cout << result.quotient << ',' << result.remainder << endl;

    // or

    auto [quotient, remainder] = divide(14, 3);

    cout << quotient << ',' << remainder << endl;
}

对于从一个函数返回多个值的通用系统,Boost tuple是我的首选。

可能的例子:

include "boost/tuple/tuple.hpp"

tuple <int,int> divide( int dividend,int divisor ) 

{
  return make_tuple(dividend / divisor,dividend % divisor )
}
std::pair<int, int> divide(int dividend, int divisor)
{
   // :
   return std::make_pair(quotient, remainder);
}

std::pair<int, int> answer = divide(5,2);
 // answer.first == quotient
 // answer.second == remainder

Std::pair本质上是你的结构解决方案,但是已经为你定义好了,并且可以适应任何两种数据类型。

在C(以及c++)标准中,有使用div、ldiv(以及C99中的lldiv)函数从<stdlib.h>(或<cstdlib>)返回结构的先例。

“返回值和返回参数的混合”通常是最不干净的。

让函数返回状态并通过返回参数返回数据在C中是合理的;在c++中,你可以使用异常来传递失败信息,这就不那么明显了。

如果有两个以上的返回值,那么类结构的机制可能是最好的。