A TR1 Tutorial: Class std::tr1::tuple

In a previous article, I gave a tutorial on the array class from the TR1 implementation released by Microsoft with the VC++ 2008 Feature Pack. In this article, I will talk about class tuple and the other classes and functions from the header with the same name, <tuple>.

Type tuple

A tuple is a sequence with a fixed number of elements of different types. The difference from an array is that a tuple is a heterogeneous sequence, whereas the array is a homogeneous sequence. Class tuple is a template class and is defined in the header <tuple> under the namespace std::tr1. Although theoretically a tuple can hold any number of elements (but finite), the implementation from VC++ 2008 Feature Pack only supports at most 15 elements.

Premises

In the examples from this tutorial, I will use a tuple with three elements, an int, a double, and a string. For the clarity of the samples, I will use this type definition:

typedef std::tr1::tuple<int, double, std::string> tuple_ids;

Also, I will use the following function for printing a tuple of the above type (I will provide details about accessing a tuple's elements in a following paragraph):

void print_tuple(const std::tr1::tuple<int, double,
                 std::string>& t)
{
   std::cout << std::tr1::get<0>(t) << " "
             << std::tr1::get<1>(t) << " "
             << std::tr1::get<2>(t) << std::endl;
}

Creating tuples

The simplest way to define a tuple is by using the default constructor:

tuple_ids t;
print_tuple(t);
0 0

Another option is using the constructor with parameters:

tuple_ids t(1, 2.5, "three");
print_tuple(t);

The output is:

1 2.5 three

A third option is creating a tuple using function make_tuple from the header <tuple>.

tuple_ids t = std::tr1::make_tuple(10, 20.5, "thirty");
print_tuple(t);
10 20.5 thirty

Tuple size

For the size of a tuple (number of elements), there is another template class called tuple_size, that has a member called value that represents the size of a tuple.

std::cout << "size: " << std::tr1::tuple_size<tuple_ids>::value
   << std::endl;
size: 3

Accessing tuple elements

To access elements from a tuple, you have to use function get:

  • Reading
  • tuple_ids t(1, 2.5, "three");
    std::cout << std::tr1::get<0>(t) << " "
              << std::tr1::get<1>(t) << " "
              << std::tr1::get<2>(t) << std::endl;
    

    the output is

    1 2.5 three
  • Writing
  • tuple_ids t;
    print_tuple(t);
    
    std::tr1::get<0>(t) = 10;
    std::tr1::get<1>(t) = 20.5;
    std::tr1::get<2>(t) = "thirty";
    print_tuple(t);
    

    the output is

    0 0
    10 20.5 thirty
    

A TR1 Tutorial: Class std::tr1::tuple

Types of elements

There is a class called tuple_element that wraps the type of a tuple element. This class has an internal typedef that is synonymous to the type of an element of a tuple (from the specified index).

tuple_ids t(100, 200.5, "three hundred");

std::tr1::tuple_element<0, tuple_ids>::type val1 =
   std::tr1::get<0>(t);
std::tr1::tuple_element<1, tuple_ids>::type val2 =
   std::tr1::get<1>(t);
std::tr1::tuple_element<2, tuple_ids>::type val3 =
   std::tr1::get<2>(t);

std::cout << "val1 = " << val1 << std::endl;
std::cout << "val2 = " << val2 << std::endl;
std::cout << "val3 = " << val3 << std::endl;
100 200.5 three hundred

Operators

The first provided operator is the assignment operator.

tuple_ids t1(1, 2.5, "three");
print_tuple(t1);

tuple_ids t2;
t2 = t1;
print_tuple(t2);

tuple_ids t3(100, 200.5, "three hundred");
t1 = t3;
print_tuple(t1);
1 2.5 three
1 2.5 three
100 200.5 three hundred

Then, there are the == and != operators. The first operator (==) returns true if the size is 0 or each element from the first tuple is equal to the corresponding element from the second tuple. The second operator (!=) returns false if the size is 0 or at least one element from the first tuple is not equal to the corresponding element from the second tuple. Comparison can only be performed for tuples of the same type.

tuple_ids t1(1, 2.0, "one");
tuple_ids t2(2, 2.0, "one");

std::cout << "t1 == t1: " << std::boolalpha << (t1 == t1)
   << std::endl;
std::cout << "t1 == t2: " << std::boolalpha << (t1 == t2)
   << std::endl;
t1 == t1: true
t1 == t2: false

Other implemented operators are >, >=, < si <=. They are all defined in terms of operator <.

This operator returns true when the size of the tuple is greater than 0 and the first element (no matter the index) from the first tuple is smaller than the corresponding element from the second tuple.

tuple_ids t1(1, 2.0, "one");
tuple_ids t2(2, 2.0, "one");
tuple_ids t3(1, 3.0, "one");
tuple_ids t4(1, 2.0, "four");

std::cout << "t1 < t2: " << std::boolalpha << (t1 < t2)
   << std::endl;
std::cout << "t1 < t3: " << std::boolalpha << (t1 < t3)
   << std::endl;
std::cout << "t1 < t4: " << std::boolalpha << (t1 < t4)
   << std::endl;
t1 < t2: true
t1 < t3: true
t1 < t4: false

Tying variables in a tuple

You can create a tuple from references to objects by using function tie.

tuple_ids t(1, 2.5, "three")

int v1 = 10;
double v2 = 20.5;
std::string v3 = "thirty";
std::cout << "before tying..." << std::endl;
std::cout << v1 << " " 
          << v2 << " "
          << v3 << std::endl;

std::tr1::tie(v1, v2, v3) = t;
std::cout << "after tying..." << std::endl;
std::cout << v1 << " " 
          << v2 << " "
          << v3 << std::endl;
before tying...
10 20.5 thirty
after tying...
1 2.5 three

A TR1 Tutorial: Class std::tr1::tuple

Swapping

You can swap the content of two tuples either by using the method swap from class tuple, or the function with the same name from header <tuple>.

tuple_ids a(1, 2, "three");
tuple_ids b(4, 5, "six");

std::cout << "before swapping" << std::endl;
print_tuple(a);
print_tuple(b);

std::cout << "after first swapping" << std::endl;
a.swap(b);
print_tuple(a);
print_tuple(b);

std::cout << "after second swapping" << std::endl;
std::tr1::swap(a, b);
print_tuple(a);
print_tuple(b);
before swapping
1 2 three
4 5 six
after first swapping
4 5 six
1 2 three
after second swapping
1 2 three
4 5 six

Debugger Support

As in the case of array and the other STL containers, the debugger shows the content of a tuple in a friendly manner, as shown in the following image.

[tupledebugger.png]

Conclusions

Although class array is useful for homogenous sequences with a given length, class tuple is useful for heterogenous sequences with a given length. It allows you to define fixed sequences with elements of different types.



About the Author

Marius Bancila

Marius Bancila is a Microsoft MVP for VC++. He works as a software developer for a Norwegian-based company. He is mainly focused on building desktop applications with MFC and VC#. He keeps a blog at www.mariusbancila.ro/blog, focused on Windows programming. He is the co-founder of codexpert.ro, a community for Romanian C++/VC++ programmers.

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: September 10, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild". This loop of continuous delivery and continuous feedback is …

  • As mobile devices have pushed their way into the enterprise, they have brought cloud apps along with them. This app explosion means account passwords are multiplying, which exposes corporate data and leads to help desk calls from frustrated users. This paper will discover how IT can improve user productivity, gain visibility and control over SaaS and mobile apps, and stop password sprawl. Download this white paper to learn: How you can leverage your existing AD to manage app access. Key capabilities to …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds