// how does it work?
auto i = 0; // ??

C++11 brings us a very useful set of tools. It adds fresh air to the hard life of a programmer. The updated syntax makes the language a more modern and easier to use.

In this post let’s take a quick look at a nice keyword ‘auto’ that, at first sight might seem very simple. Though, it appears that there are still some ‘features’ behind it and worth to consider. For instance, what about references and pointers?

The Basics  

auto is very useful when you iterate over a container:

std::vector<std::string> cityList = {"Warsaw", "Cracow"};
for (std::vector<std::string>::const_iterator it = 
    cityList.begin();
    it != cityList.end(); 
    ++it)
{
    std::cout << *it << '\n';
}

A very long expression! Now, with auto, we can write:

for (auto it = cityList.cbegin(); it != cityList.cend(); ++it)
    std::cout << *it << '\n';

Or even with range based for loops (also available since C++11):

for (auto const &city : cityList)
    std::cout << city << '\n';

In general:

a_long_variable_declaration myVar = value;

Ccan be replacted with:

auto myVar = value;

A variable declared with auto is deduced at compile time and, that way, it saves a lot of typing from our side. It will be often used with complex template expressions and STL types.

Cool feature and looks easy to use…right?

Some Questions  

How about more complicated types… what about pointers and references and their constness?

double var = 10.0;
double &varRef = var;
auto varAuto = varRef;

varAuto will have double (not reference to double) type!.

double var = 10.0;
double *varPtr  = &var;
auto varAuto    = varPtr;

This time though varAuto is a pointer to double. Why is there a difference then?

From C++11 spec [pdf] 3335 - C++11 spec, 7.1.6.4): Auto (for variable declarations) is deduced the same way as when declaring a template function

template <class U> void f(U u);

As we see it will work for the normal types and pointers, but for references and const references we need to explicitly write &U or const &U. Otherwise reference or constness will be lost.

More about those rules can be found in newest Scott Meyers book:

“Effective Modern C++”:

  • Item 1 “Understand template type deduction”
  • Item 2 “Understand auto type deduction”

Some more examples below:

const float myFloat = 0.0f;
auto f = myFloat; // f is 'float', const is dropped!
f = 2.0f;         // fine :)

const auto fc = myFloat; // fc is const float of course
fc = 2.0f;               // error!

int b = 10;
const int *pb = &b;
auto ppb      = pb;  // type is const int*
*pb  = 100;          // error!
*ppb = 101;          // error!

int b = 10;
int *const pb = &b;
auto ppb      = pb;  // type is int*
*pb  = 100;          // ok
*ppb = 101;          // ok

// maybe it is better to explicitly use '*' when
// declaring a pointer. It will be more visible. 
int b = 10;
auto *pba = &b; // same type
auto pbaa = &b; // same type

Summary  

auto type deduction simplifies writing code. Basically it deduces a variable type at compile time. It’s important to remember that the whole deduction process works in the same way (with some little exceptions) as template type deduction.

Other things  

  • Decltype is keyword ‘connected’ with auto. See some more information hereand here
  • Before C++11 auto keyword was used to declare a variable with a local lifetime. Now such declaration generates error (see this msdn link). How about Gcc?