I saw a conference by Herb Sutter where he encourages every C++ programmer to use auto. 

I had to read C# code some time ago where var was extensively used and the code was very hard to understand—every time var was used I had to check the return type of the right side. Sometimes more than once, because I forgot the type of the variable after a while!

I know the compiler knows the type and I don’t have to write it, but it is widely accepted that we should write code for programmers, not for compilers. 

I also know that is more easy to write:

auto x = GetX();


Than:

someWeirdTemplate<someOtherVeryLongNameType, ...>::someOtherLongType x = GetX();


But this is written only once and the GetX() return type is checked many times to understand what type x has.

This made me wonder—does auto make C++ code harder to understand?

Short answer: More completely, my current opinion on auto is that you should use auto by default unless you explicitly want a conversion. (Slightly more precisely, "... unless you want to explicitly commit to a type, which nearly always is because you want a conversion.")

Longer answer and rationale:

Write an explicit type (rather than auto) only when you really want to explicitly commit to a type, which nearly always means you want to explicitly get a conversion to that type. Off the top of my head, I recall two main cases:


(Common) The initializer_list surprise that auto x = { 1 }; deduces initializer_list. If you don’t want initializer_list, say the type -- i.e., explicitly ask for a conversion.
(Rare) The expression templates case, such as that auto x = matrix1 * matrix 2 + matrix3; captures a helper or proxy type not meant to be visible to the programmer. In many cases, it's fine and benign to capture that type, but sometimes if you really want it to collapse and do the computation then say the type -- i.e., again explicitly ask for a conversion.


Routinely use auto by default otherwise, because using auto avoids pitfalls and makes your code more correct, more maintainable and robust, and more efficient. Roughly in order from most to least important, in the spirit of "write for clarity and correctness first":


Correctness: Using auto guarantees you’ll get the right type. As the saying goes, if you repeat yourself (say the type redundantly), you can and will lie (get it wrong). Here's a usual example: void f( const vector<int>& v ) { for( /*…* -- at this point, if you write the iterator’s type explicitly, you want to remember to write const_iterator (did you?), whereas auto just gets it right.
Maintainability and robustness: Using auto makes your code more robust in the face of change, because when the expression's type changes, auto will continue to resolve to the correct type. If you instead commit to an explicit type, changing the expression's type will inject silent conversions when the new type converts to the old type, or needless build breaks when the new type still works-like the old type but doesn't convert to the old type (for example, when you change a map to an unordered_map, which is always fine if you aren't relying on order, using auto for your iterators you'll seamlessly switch from map<>::iterator to unordered_map<>::iterator, but using map<>::iterator everywhere explicitly means you'll be wasting your valuable time on a mechanical code fix ripple, unless an intern is walking by and you can foist off the boring work on them).
Performance: Because auto guarantees no implicit conversion will happen, it guarantees better performance by default. If instead you say the type, and it requires a conversion, you will often silently get a conversion whether you expected it or not.
Usability: Using auto is your only good option for hard-to-spell and unutterable types, such as lambdas and template helpers, short of resorting to repetitive decltype expressions or less-efficient indirections like std::function.
Convenience: And, yes, auto is less typing. I mention that last for completeness because it's a common reason to like it, but it's not the biggest reason to use it.


Hence: Prefer to say auto by default. It offers so much simplicity and performance and clarity goodness that you're only hurting yourself (and your code's future maintainers) if you don't. Only commit to an explicit type when you really mean it, which nearly always means you want an explicit conversion.

Yes, there is (now) a GotW about this.
