We’ve already covered C++11 decltype and why you should start using C++11 features today. Now we will move on to one of the most widely supported C++11 features: the new auto
keyword.; auto
is supported currently by g++ as of 4.4, clang and msvc since 10. So you are safe using it today if you don’t need to support any older compilers. The auto
keyword is used to let the compiler determine the type of a variable. This seemingly simple concept can really help clean up your code in some situations. For example:
std::vector<:string>::const_iterator itr = myvec.begin();
Now becomes:
auto itr = myvec.begin();
However, this tool creates some ambiguities we aren’t really used to in C++. What is the type of auto itr
above? Is it const_iterator
or iterator
? Or how about this snippet?
auto s = *itr;
Is that an std::string
or a const std::string &
? Or something else? It turns out that it’s std::string
. This incurs a copy penalty that we might not be expecting. It was non-obvious (to me) that we can apply some modifiers to the auto keyword type to get the desired result:
const auto &s = *itr;
Stephan T. Lavavej in the GoingNative conference pointed out cases where not only can auto
introduce some performance costs if we aren’t paying attention, it can also increase performance when we aren’t paying attention. There are cases where we might accidentally apply a built in conversion and not realize it.
struct A
{
};
struct B
{
B(const A &);
};
A getAnA();
B a = getAnA(); // oops we just called a conversion, was that intentional?
auto a2 = getAnA(); // we get the exact type returned
This could potentially be very useful in the case where a complex function such as std::bind
returns a complex templated type that we naturally assign to a more user friendly std::function
. Avoiding the conversion to an std::function
may save some compile and run time overhead. It could also potentially get in your way. The actual type returned by std::bind
is unspecified. This may mean that on one platform the result of std::bind
is callable (has an implemented operator()
) and auto
works like you would expect whereas on another platform it is not callable and you just unintentionally introduced a portability issue in your code. It’s clear that auto
will go a long way towards cleaning up the way our C++ looks, but we will still have to be intelligent about what type it is choosing for us.