How much is too much with C++11 auto keyword?
I think that one should use the auto
keyword whenever it's hard to say how to write the type at first sight, but the type of the right hand side of an expression is obvious. For example, using:
my_multi_type::nth_index<2>::type::key_type::composite_key_type::
key_extractor_tuple::tail_type::head_type::result_type
to get the composite key type in boost::multi_index
, even though you know that it is int
. You can't just write int
because it could be changed in the future. I would write auto
in this case.
So if the auto
keyword improves readability in a particular case then use it. You can write auto
when it is obvious to the reader what type auto
represents.
Here are some examples:
auto foo = std::make_shared<Foo>(); // obvious
auto foo = bla(); // unclear. don't know which type `foo` has
const size_t max_size = 100;
for ( auto x = max_size; x > 0; --x ) // unclear. could lead to the errors
// since max_size is unsigned
std::vector<some_class> v;
for ( auto it = v.begin(); it != v.end(); ++it )
// ok, since I know that `it` has an iterator type
// (don't really care which one in this context)
Use auto
everywhere you can—particularly const auto
so that side effects are less of a concern. You won’t have to worry about types except in the obvious cases, but they’ll still be statically verified for you, and you can avoid some repetition. Where auto
isn't feasible, you can use decltype
to express types semantically as contracts based on expressions. Your code will look different, but it will be a positive change.
Easy. Use it when you don't care what the type is. For example
for (const auto & i : some_container) {
...
All I care about here is that i
is whatever's in the container.
It's a bit like typedefs.
typedef float Height;
typedef double Weight;
//....
Height h;
Weight w;
Here, I don't care whether h
and w
are floats or doubles, only that they are whatever type is suitable to express heights and weights.
Or consider
for (auto i = some_container .begin (); ...
Here all I care about is that it's a suitable iterator, supporting operator++()
, it's kind of like duck typing in this respect.
Also the type of lambdas can't be spelled, so auto f = []...
is good style. The alternative is casting to std::function
but that comes with overhead.
I can't really conceive of an "abuse" of auto
. The closest I can imagine is depriving yourself of an explicit conversion to some significant type -- but you wouldn't use auto
for that, you'd construct an object of the desired type.
If you can remove some redundancy in your code without introducing side effects, then it must be good to do so.
Counterexamples (borrowed from someone else's answers):
auto i = SomeClass();
for (auto x = make_unsigned (y); ...)
Here we DO care what the type is, so we should write Someclass i;
and for(unsigned x = y;...