I am deeply suspicious of auto and decltype. I acknowledge that I am on the opposite side of the argument to people such as Bjarne Stroustrup, Herb Sutter and Scott Meyers. This is not a comfortable place to be. I picked these three luminaries because it is easy to find quotes from them – I am sure there are plenty of other people who agree with them.
Unless there is a good reason not to, use auto in small scopes
Bjarne Stroustrup The C++ Programming Language 4th edition, 220.127.116.11
Almost Always Auto
Herb Sutter Almost Always Auto
Prefer auto to explicit type declarations
Scott Meyers Effective Modern C++ (Early release) Item 5
This is not an attempt to trash any of these authors – I have quoted their conclusions however, they have well thought through reasons backing up those conclusions. I highly recommend reading the entire pieces that I took these quotes from – as always with Stroustrup, Sutter and Meyers, even when I disagree with their conclusions (which isn’t that often) I learn something from their arguments. All three authors talk about the problems that can arise from auto – note that even in the quotes I have picked there are phrases like “unless there is a good reason not to”, “almost always” and “prefer”.
I think my main disagreement is with the weighting given to some of the disadvantages. My objection to
auto can be summarized as “makes code easier to write, makes it harder to read”, and I weight this very highly, as someone who has spent a fair amount of his career trying to get up to speed with large codebases written by someone else, and trying to get new team members up to speed with large codebases written partially by me.
For example, I joined a team with a large, pre-existing, pre-C++11 codebase that used compiler extensions to fake
decltype. Learning the codebase was made far more difficult by the absence of explicitly named types in many functions. The code would not have compiled unless all the types were compatible, that’s good, however I want to know more than that. I want to know what the types are so that I can go and look them up and find out what else they can do for me. I want to look at a function and know what types are the same and what aren’t. Sooner or later I am going to make changes to that function – the changes I can make will be constrained by what the types let me do (and if the types constrain me too much I am going to have to either extend the types or use different types). I am saying “types” over and over again – they’re a big deal.
I want to know what type everything is, and I weight that desire very highly.
There will be IDEs which will make it easy to discover the types being deduced, however as Scott Meyers acknowledges in Item 4 of “Effective Modern C++” they don’t do a perfect job (although I assume that will improve), and not all of us are in a position to use IDEs anyway.
Type deduction is not new in C++ – we’ve been using templates for years, and I have fewer objections to using templates. I am trying to work out why I find templates more acceptable than
Reason #1 has to be that I am more used to templates than I am to
auto. It takes me time to get used to a new feature. However, there is more to it than that.
Template types still have a name. Imagine this introduction to a template class:
template< typename ITERATOR >
Within the class we don’t know exactly what the type of
ITERATOR is, however the name gives us a strong hint that it should be some sort of iterator.
The fact that the template types have a name also lets us see what relation (if any) there is between types in a piece of code. Contrast this:
auto i( someFunction() ); auto j( someOtherFunction() );
ITERATOR i( someFunction() ); ITERATOR j( someOtherFunction() );
The template version makes it clear that
j are the same type.
On the one hand I dislike the argument “this feature can be misused so we shouldn’t ever use it”, on the other hand I have already seen this feature be massively misused, and I suspect that it will be misused more often than not. Herb Sutter writes:
Remember that preferring auto variables is motivated primarily by correctness, performance, maintainability, and robustness – and only lastly about typing convenience.
Herb Sutter Almost Always Auto
I think this is fine advice, I think that everyone in the world should stick to it. I do not believe that they will. In my experience (and I really hope that other people have different experiences), saving some typing often outweighs everything else. Delayed gratification is an unknown concept in many programming shops.
With more experience I might come around to
auto. There are certainly people who have thought about this more deeply than I have who are in favour of
auto. There are also definitely places where
auto will help in template code. I know I dismissed the “reduces typing” argument earlier, but it would be really nice to avoid have to type
typename quite so often.
A little more follow up on the team using the compiler extension versions of
decltype. Their use of
auto was problematic, it was also exacerbated by a number of other factors. The team loved macros and loved token pasting (
##). There were many classes whose declaration and definition were created using macros, and the name of the class was generated using token pasting. Combine that with their use of
auto and there were classes whose full name never appeared in the code. They were impossible to grep for and I doubt that there were many IDEs (which that team wasn’t using anyway) that would have helped. I did not last very long on that team.