For those of us migrating from C or pre-2011 C++, the auto
keyword in Modern C++ can have us scratching our heads a bit, when we first encounter it. Initially, auto
seems to run counter to the generally strong typing philosophy of C++. Declaring variable types has been drilled into us very early on, so it’s not what we’re used to. Also, using auto
can obscure the type of an object, which seems inconvenient.
But it’s worth persevering with the auto
idiom. Apart from the surface convenience and saving a bit of typing, it can make designs more flexible as well as enhancing code readability.
Many of the best examples for this come from container templates, and – more generally – writing generic code. Suppose you’re using a std::map
, and you want to get hold of an iterator. Non-auto
syntax looks something like this:
std::map<my_first_type, my_second_type> my_stuff;
// ... maybe put some elements in my_map ...
std::map<my_first_type, my_second_type>::iterator itr = my_stuff.begin();
With the auto
keyword, the last line becomes:
auto itr = my_stuff.begin();
… which seems very obviously better. Firstly – it’s easier to parse in our heads. It’s easy to see that itr
is the beginning iterator of the my_stuff
container, without having to wade through all the verbose type information that (most of the time) doesn’t help us understand what the code is doing.
Secondly, it’s more flexible. If we change my_stuff
to a std::multimap
, we don’t have to change the iterator line. You can get some of these advantages with type aliases, but they need to be declared in separate lines, so they’re less of an advantage.
The underlying point is that the compiler already knows the type on the right of the declaration, so why should you have to re-state it explicitly? This part of the general trend in Modern C++ to make the compiler do as much as possible.
Of course, as with most things in C++, there are pitfalls. This:
std::string my_string = "hello, world!";
… is most definitely not equivalent to this:
auto my_string = "hello, world!";
… because my_string
goes from being a string object to a char
array pointer. There are subtler and less-obvious ways to make mistakes, too. Of course, when in doubt, you can always drop back to explicit types.
The auto
keyword is part of the wider type-deduction system of Modern C++. This set of rules has grown significantly since C++98, and it’s worth understanding. These examples only scratch the surface of both the advantages and ‘gotchas’ of auto
, and these are much easier to understand when you’ve got your head around type deduction.
Scott Meyers discusses it in detail in his book Effective Modern C++. It’s part of the excellent Effective C++ series, and if you’re looking to upgrade your skills from pre-Modern to Modern C++, it really is the ‘go to’ resource.
So this post is really more of a pointer to further research in books like Effective Modern C++, but experimenting with auto
is a worthwhile exercise. More on this keyword and type deduction in future posts…