Rule A8-4-4 (advisory, design, automated)

Multiple output values from a function should be returned as a struct or tuple.

Rationale

Returning multiple values from a function using a struct or tuple clearly states output parameters and allows to avoid confusion of passing them as a reference in a function call. Returning a struct or tuple will not have an additional overhead for compilers that support return-value-optimization. In C++14, a returned tuple can be conveniently processed using std::tie at the call site, which will put the tuple elements directly into existing local variables. In C++17,

structured bindings allow to initialize local variables directly from members or elements of a returned struct or tuple. Note: For return types representing an abstraction, a struct should be preferred over a generic tuple. Note: This rule applies equally to std::pair, which is a special kind of tuple for exactly two elements.

Example

// $Id: A8-4-4.cpp 289816 2017-10-06 11:19:42Z michal.szczepankiewicz $

#include <tuple>

// Non-compliant, remainder returned as the output parameter
int Divide1(int dividend, int divisor, int& remainder)
{
remainder = dividend % divisor;
return dividend / divisor;
}

// Compliant, both quotient and remainder returned as a tuple
std::tuple<int, int> Divide2(int dividend, int divisor)
{
return std::make_tuple(dividend / divisor, dividend % divisor);
}

// Compliant since C++17, return tuple using list-initialization
// std::tuple<int, int> Divide3(int dividend, int divisor)
//{
//return { dividend / divisor, dividend % divisor };
//}

int main()
{
int quotient, remainder;
std::tie(quotient, remainder) = Divide2(26, 5); // store in local variables
// auto [quotient, remainder] = Divide3(26, 5); // since C++17, by
// structured bindings
return 0;
}

See also

C++ Core Guidelines [11]: F.21: To return multiple ”out” values, prefer returning a tuple or struct.