In C++11, auto
has new meaning: it allows you to automatically deduce the type of a variable.
Why is that ever useful? Let's consider a basic example:
std::list<int> a;
// fill in a
for (auto it = a.begin(); it != a.end(); ++it) {
// Do stuff here
}
The auto
there creates an iterator of type std::list<int>::iterator
.
This can make some seriously complex code much easier to read.
Another example:
int x, y;
auto f = [&]{ x += y; };
f();
f();
There, the auto
deduced the type required to store a lambda expression in a variable.
Wikipedia has good coverage on the subject.
auto
can aid performance by avoiding silent implicit conversions. An example I find compelling is the following.
std::map<Key, Val> m;
// ...
for (std::pair<Key, Val> const& item : m) {
// do stuff
}
See the bug? Here we are, thinking we're elegantly taking every item in the map by const reference and using the new range-for expression to make our intent clear, but actually we're copying every element. This is because std::map<Key, Val>::value_type
is std::pair<const Key, Val>
, not std::pair<Key, Val>
. Thus, when we (implicitly) have:
std::pair<Key, Val> const& item = *iter;
Instead of taking a reference to an existing object and leaving it at that, we have to do a type conversion. You are allowed to take a const reference to an object (or temporary) of a different type as long as there is an implicit conversion available, e.g.:
int const& i = 2.0; // perfectly OK
The type conversion is an allowed implicit conversion for the same reason you can convert a const Key
to a Key
, but we have to construct a temporary of the new type in order to allow for that. Thus, effectively our loop does:
std::pair<Key, Val> __tmp = *iter; // construct a temporary of the correct type
std::pair<Key, Val> const& item = __tmp; // then, take a reference to it
(Of course, there isn't actually a __tmp
object, it's just there for illustration, in reality the unnamed temporary is just bound to item
for its lifetime).
Just changing to:
for (auto const& item : m) {
// do stuff
}
just saved us a ton of copies - now the referenced type matches the initializer type, so no temporary or conversion is necessary, we can just do a direct reference.
Best Answer
The
auto
keyword of C++11 is far less heavyweight than templates - its compile-time "overhead" is comparable to that ofsizeof
, which means it's close to zero.Unlike templates where the compiler needs to perform sizeable amount of computation during the expansion (the template language in C++ is Turing-complete), the
auto
keyword requires the compiler to figure out the type of an expression, which is something the compiler knows anyway. In fact, it would have to figure out the type of the expression even without theauto
keyword to decide if type conversions need to be applied.