30 May 2013

Auto keyword in C++11

// 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?

// Updated in April 2015 \\

Basics

auto is very useful in situations like:
std::vector<std::string> cityList = {"Warsaw", "Cracow"};
for (std::vector<std::string>::const_iterator it = 
    cityList.begin();
    it != cityList.end(); 
    ++it)
{
    std::cout << *it << std::endl;
}
A very long expression! Now, with auto, we can write:
for (auto it = cityList.cbegin(); it != cityList.cend(); ++it)
    std::cout << *it << std::endl;

// or even:
for (auto const &city : cityList)
    std::cout << city << std::endl;
In general:
a_long_variable_declaration myVar = value;
can 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?

The questions

But what 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 here and 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?

Links

Interested in new blog posts and bonus content? Sign up for my newsletter.

© 2017, Bartlomiej Filipek, Blogger platform
Any opinions expressed herein are in no way representative of those of my employers.
This site contains ads or referral links, which provide me with a commission. Thank you for your understanding.