Short answer: More completely, my current opinion on auto is that you should useauto 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_listsurprise thatauto x = { 1 };deducesinitializer_list. If you don’t wantinitializer_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
autoguarantees 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 writeconst_iterator(did you?), whereasautojust gets it right. - Maintainability and robustness: Using
automakes your code more robust in the face of change, because when the expression's type changes,autowill 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 amapto anunordered_map, which is always fine if you aren't relying on order, usingautofor your iterators you'll seamlessly switch frommap<>::iteratortounordered_map<>::iterator, but usingmap<>::iteratoreverywhere 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
autoguarantees 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
autois your only good option for hard-to-spell and unutterable types, such as lambdas and template helpers, short of resorting to repetitivedecltypeexpressions or less-efficient indirections likestd::function. - Convenience: And, yes,
autois 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 should be a GotW about this. This suffices for now. :)
Reference:
http://programmers.stackexchange.com/questions/180216/does-auto-make-c-code-harder-to-understand/
本文探讨了在C++编程中使用auto关键字的好处。它不仅简化了代码书写,还能提高代码的正确性和可维护性,并有助于提升性能。通过避免显式类型声明,可以减少错误并增强代码的灵活性。
1028

被折叠的 条评论
为什么被折叠?



