Auto is acceptable for iterators and, in some cases, references to complicated containers. Don't fucking type "auto pos" instead of "Vec2i pos", "Vec3f pos", or one of many other possible types that pos variable may represent.
Auto is acceptable for iterators and, in some cases, references to complicated containers. Don't fucking type "auto pos" instead of "Vec2i pos", "Vec3f pos", or one of many other possible types that pos variable may represent.
1. Sometimes `auto` helps readability immensely. Sometimes it hurts immensely.
2. All generalizations about when and where to use it are generalizations and likely to start an argument.
3. Ultimately it's up to you and your diff reviewers to do the right thing. There will be people reading your code in the future and they will judge you and your decision, so choose wisely. Future-you included.
4. `auto` can often improve correctness/generality, not just readability, e.g. "int sz = v.size(); //BAD". No one writes "vector<int>::size_type sz = v.size();" I dare you to search your code for it.
5. The only controversial generalization I feel safe making, knowing saying it will get me into trouble, is that experienced non-C++11 (whether coming from C++03 or other languages) coders tend to be more apprehensive and cautious, using `auto` less than experienced C++11 programmers. Take it for what it's worth.
For point 5 where do you find these experienced C++11 programmers that aren't coming from earlier flavours of C++?
It's possible that I misunderstood what you read so in that case could you please clarify what you meant?
2. Agree
3. Agree
4. I don't use vector<int>::size_type and I don't use decltype(sz) throughout the rest of the function. I use size_t and let the compiler give me an error if size() happens to return a different type or, if when making use of sz, types get mixed.
5. That's a little too anecdotal and 'appeal to authority' for my liking.
The big question, I suppose, is defining guidelines for when auto helps readability and when it hurts it. My experience has been that it is best to default to no auto and only use auto after trying the non-auto way first. Iterators and template-heavy containers are great instances where auto helps. In our codebase I can't think of another situation in which auto would be useful.
We also don't have heavy template usage outside of containers. If your code has templates everywhere then I can imagine the number of times auto is an improvement in readability would be larger.
There have been exceptionally few times where I have jumped into someone else's code and said "wow, their heavy use of auto has made this easier to read and understand".
'There have been exceptionally few times where I have jumped into someone else's code and said "wow, their heavy use of auto has made this easier to read and understand".'
I think it's far easier to notice when you hit unreadable code and what seems to be making it unreadable, than it is to notice when you hit readable code and what seems to be making it unusually readable. That's not to say your conclusions are necessarily wrong (or right), by any means - just that I'd view this particular argument with an added measure of skepticism.
No, but plenty of people write "size_t sz = v.size();" which is equivalent (or superior) in the vast majority of real code. And in the rare situation where the return value of size() is not an unsigned integral type, obscuring that fact with auto is bad form.
The sensible generalization for auto is to use it to avoid specifying ugly template specializations when they are both clear from the context and otherwise unavoidable. So "auto it = x.find(f);" is clearly superior to "std::unordered_map<foo, bar, foobar_hash>::iterator it = x.find(f);" etc.
The real danger with auto is to use it when you don't know what the real type actually is, which is what people are tempted to do. But if you type "auto sz = v.size();" when you've specified some unusual template arguments that cause size() to return uint16_t, you're now obscuring the unusually small width of sz which could plausibly lead to integer overflow.
I just added links to several of Herb Sutters articles (e.g., http://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-... ) and Scott Meyers talk (http://vimeo.com/channels/ndc2014/97318797 )
They say it better than I really could, and they say it very emphatically. I think the general consensus amongst the C++ leadership is to use auto when possible, for more reasons than I had considered.
edit: I notice you also object to 'appeals to authority'. In this case I am not saying do it because all of the known C++ authority tell you to do it, but indicating that they /also/ recommend it, hopefully adding more weight to the argument
Also, what's wrong with appealing to authority on difficult subject matter? Whats the point of attending Scott Meyers' lectures at all if you aren't going to heed his advice???
Nearly 100% of the time, you know what the type of a local variable is (otherwise people would be unable to use Python/Ruby/Javascript/etc.), so it's no great harm to readability. Furthermore, you are probably already working with an IDE that can tell you the type of a variable when you hover over it, anyway. I think that it also leads you to think more about interfaces than specific types.
auto bla = obj->GetBla();
bla[x] = y;
The assignment adds a new element or overwrites an existing element to the map, it will never crash.
Now during a refactoring obj->GetBla() is changed to return a vector<int>. In conventional code the build would break with an incompatible type error, the coder investigates, sees what's wrong and fixes the problem. With the auto statement the code would compile, but the bla[x] = y; would very likely not do what was intended (it can overwrite foreign memory or produce a segfault).
Is this not seen as a problem? I do use auto here and there where the type is obvious (for instance written on the right-hand-side of the assignment), but using 'auto wherever possible' is terrible advice IMHO, since it completely undermines type safety.
[edit: typos and formatting]
I do agree that jumping into a new code base can be slightly more trickier if type inference is used, but it's a minor point compared to the benefits in my opinion.
If you cherry pick something like Vec2i, type inference doesn't look that good, but the benefits are clearer from more complex code.
The example posted is a horrible use of autocomplete.
>const int calculated = [&] { auto l = lock(); auto first = stage1(); auto second = stage2(); return combine(first, second); }()
No idea what that does. It takes 2 variables of some type and does something too them. There is some sort of lock there too. I guess.
The problem here is poorly written code. I shouldn't need an IDE to tell me what is going on, the code should do it.
Clearly that was an example created to demonstrate the lambda idiom, it wasnt real code
return combine( stage1(), stage2() )
bother you too? because that infers the return-types of stage1() and stage2() as well.Why don't I use an IDE to read it? No, how about why doesn't the original coder write the code for other people to read, instead of forcing me to use an entire IDE just to piece together what they're doing, like I'm some kind of code archaeologist.
I'm debugging this thing across a flaky modem line through which I'm getting an echoed terminal, I've managed to get gdb running and narrowed it down to a handful of suspicious lines of code, and the gimboid who wrote it assumed that everyone who ever looked at it would actually be using Visual Studio 20-whatever with all the plug-ins, rather than plain text a line at a time. Brilliant.