The type std::tuple
can bundle any number of values, potentially including values of different types, into a single return object:
std::tuple<int, int, int, int> foo(int a, int b) { // or auto (C++14)
return std::make_tuple(a + b, a - b, a * b, a / b);
}
In C++17, a braced initializer list can be used:
std::tuple<int, int, int, int> foo(int a, int b) {
return {a + b, a - b, a * b, a / b};
}
Retrieving values from the returned tuple
can be cumbersome, requiring the use of the std::get
template function:
auto mrvs = foo(5, 12);
auto add = std::get<0>(mrvs);
auto sub = std::get<1>(mrvs);
auto mul = std::get<2>(mrvs);
auto div = std::get<3>(mrvs);
If the types can be declared before the function returns, then std::tie
can be employed to unpack a tuple
into existing variables:
int add, sub, mul, div;
std::tie(add, sub, mul, div) = foo(5, 12);
If one of the returned values is not needed, std::ignore
can be used:
std::tie(add, sub, std::ignore, div) = foo(5, 12);
Structured bindings can be used to avoid std::tie
:
auto [add, sub, mul, div] = foo(5,12);
If you want to return a tuple of lvalue references instead of a tuple of values, use std::tie
in place of std::make_tuple
.
std::tuple<int&, int&> minmax( int& a, int& b ) {
if (b<a)
return std::tie(b,a);
else
return std::tie(a,b);
}
which permits
void increase_least(int& a, int& b) {
std::get<0>(minmax(a,b))++;
}
In some rare cases you'll use std::forward_as_tuple
instead of std::tie
; be careful if you do so, as temporaries may not last long enough to be consumed.