3 ms·
Ah yes, the type inference argument. I give the onboarding here for new hires about C++ and so I get some form of this objection (and the subsequent argument) e
by lbrandy 12y ago
Ah yes, the type inference argument. I give the onboarding here for new hires about C++ and so I get some form of this objection (and the subsequent argument) every two weeks like clockwork. Here's what I say (feedback welcome):
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.
- fredophile 12y agoI've got a legit question that sounds sort of like trolling but I can't think of a better way to word it. 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?
- lbrandy 12y agoWhat I mean is that (and again, I know this is a gross generalization), on average, experienced engineers new to C++11 tend to be pretty anti-auto and tend to soften their stance on `auto` over time.
- forrestthewoods 12y ago1. Agree 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".
- dllthomas 12y agoI've no dog in this fight, but narrowly with regard to '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.
- AnthonyMouse 12y ago> No one writes "vector<int>::size_type sz = v.size();" 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.