Book Image

Learning Boost C++ Libraries

By : Arindam Mukherjee
Book Image

Learning Boost C++ Libraries

By: Arindam Mukherjee

Overview of this book

Table of Contents (19 chapters)
Learning Boost C++ Libraries
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

C++11 auto and Boost.Auto


Consider how you declare an iterator to a vector of strings:

std::vector<std::string> names;
std::vector<std::string>::iterator iter = vec.begin();

The declared type of iter is big and unwieldy and it is a pain to write it explicitly every time. Given that the compiler knows the type of the initializing expression on the right-hand side, that is, vec.begin(), this is also superfluous. Starting with C++11, you can use the auto keyword to ask the compiler to deduce the type of a declared variable using the type of the expression it is initialized with. Thus, the preceding tedium is replaced by the following:

std::vector<std::string> names;
auto iter = vec.begin();

Consider the following statement:

auto var = expr;

The deduced type of var is the same as the deduced type T, when the following function template is called with the argument expr:

template <typename T>
void foo(T);

foo(expr);

Type deduction rules

There are a few rules to keep in mind. First, if the initializing expression is a reference, the reference is stripped in the deduced type:

int x = 5;
int& y = x;
auto z = y;  // deduced type of z is int, not int&

If you want to declare an lvalue-reference, you must explicitly adorn the auto keyword with an ampersand (&), as shown here:

int x = 5;
auto& y = x;     // deduced type of y is int&

If the initializing expression is not copyable, you must make the assignee a reference in this way.

The second rule is that const and volatile qualifiers of the initializing expression are stripped in the deduced type, unless the variable declared with auto is explicitly declared as a reference:

int constx = 5;
auto y = x;     // deduced type of y is int
auto& z = x;    // deduced type of z is constint

Again, if you want to add a const or volatile qualifier, you must do so explicitly, as shown:

intconst x = 5;
auto const y = x;    // deduced type of y is constint

Common uses

The auto keyword is very convenient to use in a lot of situations. It lets you get away from having to type long template IDs, in particular when the initializing expression is a function call. Here are a couple of examples to illustrate the advantages:

auto strptr = boost::make_shared<std::string>("Hello");
// type of strptr is boost::shared_ptr<std::string>

auto coords(boost::make_tuple(1.0, 2.0, 3.0));
// type of coords is boost::tuple<double, double, double>

Note the savings in the type names achieved through the use of auto. Also, note that while creating the tuple called coords using boost::make_tuple, we do not use the assignment syntax for initialization.

Boost.Auto

If you are on a pre-C++11 compiler, you can emulate this effect using the BOOST_AUTO and BOOST_AUTO_TPL macros. Thus, you can write the last snippet as follows:

#include <boost/typeof/typeof.hpp>

BOOST_AUTO(strptr, boost::make_shared<std::string>("Hello"));
// type of strptr is boost::shared_ptr<std::string>

BOOST_AUTO(coords, boost::make_tuple(1.0, 2.0, 3.0));
// type of coords is boost::tuple<double, double, double>

Note the header file boost/typeof/typeof.hpp that needs to be included to use the macro.

If you want to declare a reference type, you can adorn the variable with a leading ampersand (&). Likewise, to qualify your variable with const or volatile, you should add the const or volatile qualifier before the variable name. Here is an example:

BOOST_AUTO(const& strptr, boost::make_shared<std::string>("Hello"));
// type of strptr is boost::shared_ptr<std::string>