Returning multiple values from a C++ function

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 is essentially your struct solution, but already defined for you, and ready to adapt to any two data types.


For returning two values I use a std::pair (usually typedef'd). You should look at boost::tuple (in C++11 and newer, there's std::tuple) for more than two return results.

With introduction of structured binding in C++ 17, returning std::tuple should probably become accepted standard.


Personally, I generally dislike return parameters for a number of reasons:

  • it is not always obvious in the invocation which parameters are ins and which are outs
  • you generally have to create a local variable to catch the result, while return values can be used inline (which may or may not be a good idea, but at least you have the option)
  • it seems cleaner to me to have an "in door" and an "out door" to a function -- all the inputs go in here, all the outputs come out there
  • I like to keep my argument lists as short as possible

I also have some reservations about the pair/tuple technique. Mainly, there is often no natural order to the return values. How is the reader of the code to know whether result.first is the quotient or the remainder? And the implementer could change the order, which would break existing code. This is especially insidious if the values are the same type so that no compiler error or warning would be generated. Actually, these arguments apply to return parameters as well.

Here's another code example, this one a bit less trivial:

pair<double,double> calculateResultingVelocity(double windSpeed, double windAzimuth,
                                               double planeAirspeed, double planeCourse);

pair<double,double> result = calculateResultingVelocity(25, 320, 280, 90);
cout << result.first << endl;
cout << result.second << endl;

Does this print groundspeed and course, or course and groundspeed? It's not obvious.

Compare to this:

struct Velocity {
    double speed;
    double azimuth;
};
Velocity calculateResultingVelocity(double windSpeed, double windAzimuth,
                                    double planeAirspeed, double planeCourse);

Velocity result = calculateResultingVelocity(25, 320, 280, 90);
cout << result.speed << endl;
cout << result.azimuth << endl;

I think this is clearer.

So I think my first choice, in general, is the struct technique. The pair/tuple idea is likely a great solution in certain cases. I'd like to avoid the return parameters when possible.


In C++11 you can:

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

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

or with structs:

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

Tags:

C++