Browse DevX
Sign up for e-mail newsletters from DevX


Tackle Common Programming Tasks Using the New <tuple> Library-3 : Page 3

Tuples are fixed size collections of heterogeneous objects, and they are being added to the C++ standard. Learn how this powerful facility can help you simplify several common programming tasks.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Tuples in the Real World
Let's examine some of the uses of tuple types. Suppose you need to implement a function that translates a file name into both FILE * and a file descriptor. C++ of course doesn't allow more than one return type. A common workaround is to define two functions with slightly different names:

int convert_filename(const char * path);
FILE * fconvert_filename(const char * path);

The POSIXlibraries are replete with such sets of functions. Overloading won't do in this case because you can't define overloaded versions of a function that differ only in their return types:

int convert_filename(const char* path);
FILE* convert_filename(const char* path); //error

By using a tuple type to pack the two return types, you can simulate multiple return types for a single function. As always, use a typedefto hide the cumbersome syntax:

typedef tuple<int, FILE *> file_t;
file_t convert_filename(const char* path);

In an object-oriented environment you can extend file_t to accommodate an fstreamobject as well.

A tuple type provides a neat solution to another problemthat I presented here several months ago, namely simulating floating point values with integers. Instead of using two bare integers, you can now use a tuple:

typedef tuple<__int64, int> Currency;

The revised class USD now looks like this:

class USD
 Currency curr;
 explicit USD(__int64 d=0, int c=0): curr(d,c) {}

As an aside, notice how important it is to declare data members private. Users of this class won't notice that its implementation has changed because the interface remains intact.

This is very nice, but you're probably asking: "Can't I just pack the two integers in a good ol' struct instead?" Of course you can. However, a tuple offers a bonus: it already overloads the relational operators <, >, ==,etc. Consequently, you can compare two currency values without any effort:

bool operator==(const USD& u1, const USD& u2)
 return u1.curr==u2.curr;

The tuple's overloaded == returns true if and only if each element in u1 is equal to the corresponding element in u2. For example:

Currency curr1(100,99);  
Currency curr2(100,98);
Currency curr3(100,98);

bool res=curr1==curr2; //false
res=curr2==curr3; //true

The Top of the Poll
Tuples have many other uses. For example, you can create a tuple of references and cv-qualified types:

int i; char c; 
make_tuple(ref(i),ref(c)); // tuple <int &, char&>
make_tuple(cref(i), c); // tuple <const int &, char>

The ref class template serves a reference wrapper. Likewise, cref wraps a reference to a const object. To simplify the creation of tuples of reference elements, use the tie()function:

tie(i, c); //same as: make_tuple(ref(i), ref(c));

A tuple containing non-const reference elements can be used to "unpack" another tuple into real objects:

tie(i, c)=make_tuple(1, 'a');

After the assignment, i=1 and c='a'. This technique may be useful when unpacking a function that returns a tuple.

Danny Kalev is a certified system analyst and software engineer specializing in C++. He was a member of the C++ standards committee between 1997 and 2000 and has since been involved informally in the C++0x standardization process. He is the author of "The ANSI/ISO Professional C++ Programmer's Handbook" and "The Informit C++ Reference Guide: Techniques, Insight, and Practical Advice on C++."
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date