C++ Tutorial: Use std::tuple To Simulate Compact Heterogeneous Containers | CodeGuru

C++ Tutorial: Use std::tuple To Simulate Compact Heterogeneous Containers

Introduction Standard C++ programming containers classes such as vector and list are homogeneous, meaning they can store only one type of objects at a time. However, in some cases it’s more convenient to use a container of heterogeneous objects, which is where std::tuple comes in handy. std::tuple can store up to 10 objects of different […]

Written By
CodeGuru Staff
CodeGuru Staff
Dec 22, 2010
3 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

Introduction

Standard C++ programming containers classes such as vector and list are homogeneous, meaning they can store only one type of objects at a time. However, in some cases it’s more convenient to use a container of heterogeneous objects, which is where std::tuple comes in handy. std::tuple can store up to 10 objects of different types.

Suppose you need to design a function that retrieves three values from a database: an index number representing the month of the year, and two floating point numbers that represent the consumer’s price index (CPI) of the relevant month, and the CPI of the previous month. Although you can split this function into two, it’s more efficient and convenient to have one function that retrieves these values in one shot. Your first step consists of defining a tuple type i.e, a specialization of the class template std::tuple. Here’s an example:

  #include <tuple>
  using namespace std;

  typedef tuple <int, double, double> CPIs;

Here’s the function declaration:

  CPIs get_cpis(const Date& d);

In the absence of explicit initializers for the tuple’s elements, the elements will be default-initialized:

  tuple <double, char> t2(3.55, 'a');// explicit
  tuple <double, int, string> t3; // <0.0,0,string()>

Helper Functions

The Standard Library defines meta-functions and helper functions for handling tuples conveniently. Meta-functions use template meta-programming to compute their results at compile time. Helper functions are free-standing functions with short and intuitive names. Let’s look at some of these.

To get the number of elements that a tuple type has, use the tuple_size() meta-function:

  #include <tuple>
  using namespace std;

  int elements=tuple_size<CPIs>::value;//3

To automate the creation of a tuple object, use the make_tuple() helper function. make_tuple() deduces the types of its arguments to create a tuple type. It returns a tuple object initialized with those arguments:

  CPIs mycpi=make_tuple(2, 0.1, 0.3);

To get the type of a tuple element, use the tuple_element() meta-function. This function is useful for traversing a tuple or when you want to create copies of a tuple’s elements without knowing the elements’ types in advance. tuple_element() takes an index and the tuple type (remember that tuples use zero-based indexing). In the following example, tuple_element() retrieves the type of the first tuple element. The result is used for declaring val, an object whose type is the same as that of the tuple’s first element:

  tuple_element <0, tuple<int, int, char> >::type val;//int

What if you need to access the actual value of a tuple element rather than its type? Use the get<n> function template. Get takes an index and returns the corresponding element’s value. The following listing uses tuple_element() to declare objects of the types of a tuple object’s elements and then calls get<n> to copy their corresponding values:

  CPIs cpi=make_tuple(4, 0.1, -0.2);
  tuple_element <0,CPIs>::type val1;//int
  tuple_element <1,CPIs>::type val2;//double
  tuple_element <2,CPIs>::type val3;//double

  val1=get<0> (mycpi);//4
  val2=get<1> (mycpi);//0.1
  val3=get<2> (mycpi);//-0.2
Advertisement

Putting it all Together

Suppose you’re designing a stock quote search engine that accepts a free text query. The engine retrieves the current stock price along with the stock’s symbol. To represent the stock prices, you use a pair of integral values for the dollars and cents (a pair of integers rather than double guarantees accurate comparisons among other things), and a string for the stock symbol. You can represent the stock price like this:

  typedef tuple<int,int,string> StockPrice1;

This design is simple but not descriptive enough — the reader has to guess that the first two integers are construed as a pair. An alternative design would use a layered structure:

  typedef tuple<int,int> Currency;
  typedef tuple<Currency, double, string > StockPrice2;

Regardless of your favorite representation, both designs exhibit the beauty of tuples. For example, to compare two StockPrice records you don’t need to overload any operators. std::tuple already includes the relevant overloaded operators for you:

  StockPrice1 get_quote(const string& query);
  StockPrice1 a(620,24,"GOOG");
  StockPrice1 b=get_quote("Google Inc.");
  if (a!=b) //is it the same quote?
...

As an aside, you’re probably wondering why I didn’t use std::pair to represent Currency. The truth is that a pair is nothing but a tuple containing two members. Historically, std::pair inspired the authors of std::tuple to design a more generalized notion of a fixed-size heterogeneous container. Of course, it doesn’t mean that you’re advised to avoid std::pair;

Conclusion

Tuples were added to C++ programming as part of the Standard Library Technical Report One (TR1 for short) which is a fancy name for what would otherwise be dubbed a service pack for the C++98 Standard Library. Virtually, every standard-compliant C++ compiler supports std::tuple today. Additionally, tuples (as all other TR1 features) are highly portable, so you can use them without hesitation in cross-platform code.

The main advantage of std::tuple is automation. Instead of inventing a heterogeneous container on your own, std::tuple will be convenient so long as you don’t need more than 10 elements and don’t expect to insert or remove elements dynamically.

Advertisement
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.