Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Boost C++ Application Development  Cookbook

You're reading from   Boost C++ Application Development Cookbook Recipes to simplify your application development

Arrow left icon
Product type Paperback
Published in Aug 2017
Publisher Packt
ISBN-13 9781787282247
Length 438 pages
Edition 2nd Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Anton Polukhin Alekseevic Anton Polukhin Alekseevic
Author Profile Icon Anton Polukhin Alekseevic
Anton Polukhin Alekseevic
Arrow right icon
View More author details
Toc

Table of Contents (13) Chapters Close

Preface 1. Starting to Write Your Application FREE CHAPTER 2. Managing Resources 3. Converting and Casting 4. Compile-Time Tricks 5. Multithreading 6. Manipulating Tasks 7. Manipulating Strings 8. Metaprogramming 9. Containers 10. Gathering Platform and Compiler Information 11. Working with the System 12. Scratching the Tip of the Iceberg

Combining multiple values into one

There is a very nice present for those who like std::pair. Boost has a library called Boost.Tuple. It is just like std::pair, but it can also work with triples, quads, and even bigger collections of types.

Getting ready

Only basic knowledge of C++ and a standard library is required for this recipe.

How to do it...

Perform the following steps to combine multiple values into one:

  1. To start working with tuples, you need to include a proper header and declare a variable:
#include <boost/tuple/tuple.hpp> 
#include <string>

boost::tuple<int, std::string> almost_a_pair(10, "Hello");
boost::tuple<int, float, double, int> quad(10, 1.0f, 10.0, 1);
  1. Getting a specific value is implemented via the boost::get<N>() function, where N is a zero-based index of a required value:
#include <boost/tuple/tuple.hpp>

void sample1() {
const int i = boost::get<0>(almost_a_pair);
const std::string& str = boost::get<1>(almost_a_pair);
const double d = boost::get<2>(quad);
}

The boost::get<> function has many overloads and is used widely across Boost. We already saw how it can be used with other libraries in the Storing multiple chosen types in a container/variable recipe.

  1. You can construct tuples using the boost::make_tuple() function, which is shorter to write, because you do not need to fully qualify the tuple type:
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>
#include <set>

void sample2() {
// Tuple comparison operators are
// defined in header "boost/tuple/tuple_comparison.hpp"
// Don't forget to include it!
std::set<boost::tuple<int, double, int> > s;
s.insert(boost::make_tuple(1, 1.0, 2));
s.insert(boost::make_tuple(2, 10.0, 2));
s.insert(boost::make_tuple(3, 100.0, 2));

// Requires C++11
const auto t = boost::make_tuple(0, -1.0, 2);
assert(2 == boost::get<2>(t));
// We can make a compile time assert for type
// of t. Interested? See chapter 'Compile time tricks'
}
  1. Another function that makes life easier is boost::tie(). It works almost as make_tuple, but adds a nonconst reference for each of the passed types. Such a tuple can be used to get values to a variable from another tuple. It can be better understood from the following example:
#include <boost/tuple/tuple.hpp>
#include <cassert>

void sample3() {
boost::tuple<int, float, double, int> quad(10, 1.0f, 10.0, 1);
int i;
float f;
double d;
int i2;

// Passing values from 'quad' variables
// to variables 'i', 'f', 'd', 'i2'.
boost::tie(i, f, d, i2) = quad;
assert(i == 10);
assert(i2 == 1);
}

How it works...

Some readers may wonder why we need a tuple when we can always write our own structures with better names; for example, instead of writing boost::tuple<int, std::string>, we can create a structure:

struct id_name_pair { 
int id;
std::string name;
};

Well, this structure is definitely clearer than boost::tuple<int, std::string>. The main idea behind the tuple's library is to simplify template programming.

There's more...

A tuple works as fast as std::pair (it does not allocate memory on a heap and has no virtual functions). The C++ committee found this class to be very useful and it was included in the standard library. You can find it in a C++11 compatible implementation in the header file <tuple> (don't forget to replace all the boost:: namespaces with std::).

The standard library version of tuple must have multiple micro optimizations and typically provides a slightly better user experience. However, there is no guarantee on the order of construction of tuple elements, so, if you need a tuple that constructs its elements starting from the first, you have to use the boost::tuple:

#include <boost/tuple/tuple.hpp>
#include <iostream>

template <int I>
struct printer {
printer() { std::cout << I; }
};

int main() {
// Outputs 012
boost::tuple<printer<0>, printer<1>, printer<2> > t;
}

The current Boost implementation of a tuple does not use variadic templates, does not support rvalue references, does not support C++17 structured bindings, and is not usable with constexpr.

See also

  • Boost's official documentation contains more examples, information about performance, and abilities of Boost.Tuple. It is available at the link http://boost.org/libs/tuple.
  • The Converting all tuple elements to a string recipe in Chapter 8, Metaprogramming, shows some advanced usages of tuples.
You have been reading a chapter from
Boost C++ Application Development Cookbook - Second Edition
Published in: Aug 2017
Publisher: Packt
ISBN-13: 9781787282247
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €18.99/month. Cancel anytime