C++ Using std::tuple


Example

C++11

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:

C++17
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);
C++17

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.