Boost.Tuple

The Boost.Tuple library allows convenient grouping of a small, fixed, number of objects of heterogeneous type with access to them by their sequence number rather than a name. This library therefore makes it easy to use programing styles which depend on sequences of anonymous elements such that are more commonly associated with the lisp or Python programming languages.

A minimal usage example is a function that uses tuple to return more than one object, in this case a return value and a boolean flag indicating if the computation is reliable:

// Without boost.tuple
double calculate(double x, double y, bool &flag)
{
  // some processing
  flag=true;
  return x;
}

// With boost.tuple
boost::tuple<double, bool>
calculate(double x, double y)
{
  // some processing
  return boost::make_tuple(x, true);
}

The key features of this library are:

  • Simple clear syntax, including easy assignment from tuples into local variables using tiers (although ties would have been a better name):

    double x;
    bool   flag;
    boost::tie(x,flag)=calculate(0,1);
    // x and flag are now set from result of calculate
    
  • Good run-time performance: usually close to, or only slightly worse then, using reference parameters to return multiple values

  • Accessibility by sequence number allows for meta-programming techniques, a feature which expanded on in the Boost.Fusion library

In deciding when to use tuples, it should be noted that they are a light-weight alternative to structures and classes. By light-weight I mean that their syntax is shorter and clearer but consequently the amount of information they convey to the programmer is smaller. Consider for example the following alternatives:

void FDF(double x, double y,
         ValueAndDiff &res)
{
  // Some calculations
  res.f= 0.5*x+0.5*y;
  res.dfdx=0.5;
  res.dfdy=0.5;
}

boost::tuple<double, double, double>
FDF(double x, double y)
{
  return boost::make_tuple(0.5*x+0.5*y,
                           0.5,
                           0.5);
}

The first version of the function FDF is far more explicit about what it is returning to the user, by using the named type ValueAndDiff and names for fields that makeup this compound type. The second version is considerably more concise but correspondingly less explicit, since the user needs to know from other sources (e.g., from documentation) what the meaning of the three numbers returned by the function is.

Therefore, the typical usage scenario for boost.tuple is a situation in which there are a large numbers of short functions all returning different quantities and are used only in a small part of application, perhaps only within a single translational unit. Examples of this would be helper functions used in implementation only and not exposed in a public interface; or, functions used for unit-testing and other test code.