255

I've been using the new auto keyword available in the C++11 standard for complicated templated types which is what I believe it was designed for. But I'm also using it for things like:

auto foo = std::make_shared<Foo>();

And more skeptically for:

auto foo = bla(); // where bla() return a shared_ptr<Foo>

I haven't seen much discussion on this topic. It seems that auto could be overused since a type is often a form of documentation and sanity checks. Where do you draw the line in using auto and what are the recommended use cases for this new feature?

To clarify: I'm not asking for a philosophical opinion; I'm asking for the intended use of this keyword by the standard committee, possibly with comments on how that intended use is realized in practice.

Alan Turing
  • 12,223
  • 16
  • 74
  • 116
  • This is a Q&A site though, not a discussion site. You asked a very very general question and I doubt that anybody will be able to give you anything other than a highly subjective one. (that's why -1) – TravisG Jun 22 '11 at 04:45
  • 18
    @heishe, I added a clarification. If you read the question very generally, it does seem to be asking a subjective opinion, but really if you used the `auto` keyword, then you know how it's **supposed** to be used. That's what I'm asking, as someone who is new to this feature, is how am I supposed to use it? – Alan Turing Jun 22 '11 at 04:50
  • 14
    I've seen this discussion all over the place when C# introduced `var` (that is, once people got over the idea that it wasn't dynamic typing after all). If you want you can start with [this question](http://stackoverflow.com/questions/41479/use-of-var-keyword-in-c) and go through the related questions. – R. Martinho Fernandes Jun 22 '11 at 05:11
  • @Lex : Interesting, then, that the answer you chose doesn't address your clarification at all, and is purely subjective (just like this question)... – ildjarn Jun 22 '11 at 20:34
  • 3
    @ildjarn, I'm sorry you feel that way. The answer I chose lists clear code snippets of good and bad uses of `auto`. Not all questions ask what is 2+2. For example, asking HOW I calculate 2+2 is still a good question, but you could easily call it "subjective". Perhaps I'm naive, but to me, if a question leads to a **useful** clarifying answer, then both the question and answer deserve to be on the site. – Alan Turing Jun 22 '11 at 20:43
  • 3
    @Lex : Either something is _legal_ or it isn't; calling something "bad" that is legal is subjective by definition. I.e., calling `auto foo = bla();` "bad" is clearly an opinion, not a fact, which makes this question and answer a discussion, which makes it relevant to Programmers SE, which is exactly what the close votes indicate. /shrug – ildjarn Jun 22 '11 at 22:22
  • 42 is the definitive answer here – sehe Sep 11 '12 at 17:30
  • 4
    Herb Sutter view on this matter: http://herbsutter.com/2013/06/13/gotw-93-solution-auto-variables-part-2/ – rafak Jun 15 '13 at 12:18
  • I personally avoid auto. Benefits: You don't need to change code if you change the type. However, how often do you change type?Rarely. Disadvantages: makes code difficult to read. – user997112 Jun 11 '20 at 02:52
  • 1
    If using something like var or auto makes your code difficult to understand the problem is your code not the keyword. – Matthew Whited May 16 '23 at 09:34

15 Answers15

158

I think that one should use the auto keyword whenever it's hard to say how to write the type at first sight, but the type of the right hand side of an expression is obvious. For example, using:

my_multi_type::nth_index<2>::type::key_type::composite_key_type::
    key_extractor_tuple::tail_type::head_type::result_type

to get the composite key type in boost::multi_index, even though you know that it is int. You can't just write int because it could be changed in the future. I would write auto in this case.

So if the auto keyword improves readability in a particular case then use it. You can write auto when it is obvious to the reader what type auto represents.

Here are some examples:

auto foo = std::make_shared<Foo>();   // obvious
auto foo = bla();                     // unclear. don't know which type `foo` has

const size_t max_size = 100;
for ( auto x = max_size; x > 0; --x ) // unclear. could lead to the errors
                                      // since max_size is unsigned

std::vector<some_class> v;
for ( auto it = v.begin(); it != v.end(); ++it )
                                      // ok, since I know that `it` has an iterator type
                                      // (don't really care which one in this context)
L. F.
  • 19,445
  • 8
  • 48
  • 82
Kirill V. Lyadvinsky
  • 97,037
  • 24
  • 136
  • 212
  • 24
    That does not seem like a very good recommendation. How often is it that you don't know the type of the object? (Outside of templates, that is.) And if you don't know they type, look it up, don't be lazy and use auto. – Paul Manta Jun 22 '11 at 05:00
  • 3
    @Paul, I added the sample of such type. I know how to write this type without `auto` (I did it), but writing this type doesn't add readability to the code. – Kirill V. Lyadvinsky Jun 22 '11 at 05:04
  • 1
    Well that's what I mean my "complicated templated types" but what about the cases I mention where I know the type but it's just too verbose? – Alan Turing Jun 22 '11 at 05:09
  • 2
    @Lex Fridman, That's the same. If it is obvious for the reader what type is behind `auto` you can write `auto`. – Kirill V. Lyadvinsky Jun 22 '11 at 05:11
  • @Krill And to that I'd add, to also use `auto` only if the type is too verbose. – Paul Manta Jun 22 '11 at 05:18
  • 13
    @Paul: often times you only know or only need to know the most important part of the type, e.g. that it is an iterator, but you don't know and don't care whether it is an iterator of vectors or iterator of linked list; in those cases, you really don't want to spend time and screen space trying to figure out how to write down the types. – Lie Ryan Jun 22 '11 at 12:58
  • 54
    Whether C++ diehards will like it or not, C++0x will attract people who would never have used C++. And those will use auto all over the place. – Prof. Falken Jun 22 '11 at 13:02
  • @Lie Ryan Cases where the type is too verbose, _and_ when it is obvious, `auto` is fine. One example, is when using iterators in a for-loop. Cases where you don't care or don't know the type of an object practically never happen. – Paul Manta Jun 22 '11 at 14:18
  • 1
    I chose this as the answer over the other several excellent answers because it has a few clear examples of when to use and not to use `auto` with a clear philosophy stated as justification. I should say, however, that the other answers are also excellent and could just as easily be chosen. – Alan Turing Jun 22 '11 at 20:46
  • 8
    @R.MartinhoFernandes - no, the only thing that is clear is that _whatever_ `bla()` returns you're giving it to `foo`. – Luis Machuca Oct 01 '13 at 20:35
  • 9
    @LuisMachuca my reply was a tongue-in-cheek way of saying that it is dishonest to give a textbook example of bad variable and function naming and to blame its lack of readability on type inference. – R. Martinho Fernandes Oct 01 '13 at 22:03
  • Heh, I guess Stack Overflow lacks a `` tag :p -- I'll have to like your comment in exchange. – Luis Machuca Oct 02 '13 at 00:26
  • 1
    Now if we go by this logic that use auto wherever it to hard to write/determine type then we are not utilizing auto capabilities like say we have std::vector vecint; and then we are taking size as unsigned sz=vecint.size() bcoz most programmers are not aware vector size function returns std::vector::size_type so unsigned then for both 32 bit and 64 bit machine it will be 32 bits only but if there they have used auto then it will have correct type of std::vector::size_type which will be 32 or 64 bit depending on machine type. this is one advantage of auto and there are many other – PapaDiHatti Jun 11 '16 at 14:59
  • @R.MartinhoFernandes " it is dishonest to give a textbook example of bad variable and function naming and to blame its lack of readability on type inference." -- Not necessarily dishonest, but rather *incompetent*. This is my first test for whether someone is a good programmer. I ask them what's wrong with `var foo = bar()`. If they complain about `var`, that's the end of the interview. – Jim Balter Jan 26 '17 at 01:33
  • 1
    come to this post as a result of a response to a PR, in this used to this post as a justification for the use of the word reserved auto in c ++ 11, the recommendation is not very justified, and does not make good programming practices , in many cases it makes the code much more illegible and very difficult to read, I think the recommendation of my part would be only to use in metaprogramming templates or in obtaining very long types. – Ricardo_arg Jun 19 '18 at 01:09
  • 1
    Nearly every advantage of 'auto' can be achieved with a 'using' statement – user997112 Sep 26 '20 at 01:28
  • I totally disagree with this answer. – BorisV Mar 16 '22 at 09:21
65

Use auto everywhere you can—particularly const auto so that side effects are less of a concern. You won’t have to worry about types except in the obvious cases, but they’ll still be statically verified for you, and you can avoid some repetition. Where auto isn't feasible, you can use decltype to express types semantically as contracts based on expressions. Your code will look different, but it will be a positive change.

Jon Purdy
  • 53,300
  • 8
  • 96
  • 166
  • 14
    I'd say particularly 'const auto&' – Viktor Sehr Aug 22 '13 at 08:15
  • 3
    Better use `auto&&` in complex situations http://edmundv.home.xs4all.nl/blog/2014/01/28/use-auto-and-and-for-range-based-for-loops/ – KindDragon Mar 06 '14 at 15:56
  • 2
    @KindDragon: That is a good rule of thumb, but I prefer to use `const auto&` or `const auto` unless I explicitly want to mutate or move. – Jon Purdy Mar 06 '14 at 18:15
  • 2
    "*Use auto everywhere you can*". Does this mean I should write `auto str = std::string();` instead of `std::string str;`? – Calmarius Mar 23 '19 at 18:42
  • 24
    Using auto all over the place will make your code less readable and harder to debug because you will have to deduce the types yourself while reading the code. – SubMachine Jul 07 '19 at 08:14
  • 5
    @SubMachine: You don't have to deduce the type yourself unless you are working with notepad instead of some proper IDEs – Young Aug 20 '20 at 05:55
  • 8
    @Young I don't say you should not use it, I say you should be smart about it - use auto where ever you believe it enhances code readability and avoid it where ever it obscures the intent of the code. "Proper" IDEs are not always available to you, and even when they do, hovering over variables to get their types is less convenient than just seeing the types as part of the code. – SubMachine Aug 21 '20 at 08:50
  • 4
    @Young Does intellisense exist in a formal code review? – user997112 Sep 26 '20 at 01:29
  • The only thing the type matters to is the compiler. For a readability aspect the names of variables and functions is much more important. – Matthew Whited May 16 '23 at 09:37
60

Easy. Use it when you don't care what the type is. For example

for (const auto & i : some_container) {
   ...

All I care about here is that i is whatever's in the container.

It's a bit like typedefs.

typedef float Height;
typedef double Weight;
//....
Height h;
Weight w;

Here, I don't care whether h and w are floats or doubles, only that they are whatever type is suitable to express heights and weights.

Or consider

for (auto i = some_container .begin (); ...

Here all I care about is that it's a suitable iterator, supporting operator++(), it's kind of like duck typing in this respect.

Also the type of lambdas can't be spelled, so auto f = []... is good style. The alternative is casting to std::function but that comes with overhead.

I can't really conceive of an "abuse" of auto. The closest I can imagine is depriving yourself of an explicit conversion to some significant type -- but you wouldn't use auto for that, you'd construct an object of the desired type.

If you can remove some redundancy in your code without introducing side effects, then it must be good to do so.

Counterexamples (borrowed from someone else's answers):

auto i = SomeClass();
for (auto x = make_unsigned (y); ...)

Here we DO care what the type is, so we should write Someclass i; and for(unsigned x = y;...

spraff
  • 32,570
  • 22
  • 121
  • 229
  • 1
    If you don't care about the type it should be templated for generic programming – user997112 Sep 26 '20 at 01:30
  • @user997112 Since C++20, the `auto` keyword can be used to [infer parameter types](https://stackoverflow.com/a/60355539/975097) in function templates. – Anderson Green Sep 03 '21 at 15:04
47

At C++ and Beyond 2012 in the Ask Us Anything panel, there was a fantastic exchange between Andrei Alexandrescu, Scott Meyers and Herb Sutter talking about when to use and not use auto. Skip to minute 25:03 for a 4 minute discussion. All three speakers give excellent points that should be kept in mind for when to not use auto.

I highly encourage people to come to their own conclusion, but my take away was to use auto everywhere unless:

  1. It hurts readability
  2. There is concern about automatic type conversion (e.g. from constructors, assignment, template intermediate types, implicit conversion between integer widths)

Liberal use of explicit helps reduce concern for the latter, which helps minimize the amount of time the former is an issue.

Rephrasing what Herb said, "if you're not doing X, Y, and Z, use auto. Learn what X, Y, and Z are and go forth and use auto everywhere else."

Sean
  • 9,888
  • 4
  • 40
  • 43
  • 4
    Probably also worth linking to "almost always auto" -- http://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/ – Rob Starling Apr 06 '16 at 05:56
  • Nice referral... great talk. Herb changed my mind about ``auto`` use. – kmiklas Jan 05 '21 at 16:43
  • here is the advice in cppCoreGuidelines (which has Herb Sutter and Bjarne Stroustrup as authors) : https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es11-use-auto-to-avoid-redundant-repetition-of-type-names – kingsjester Jul 23 '22 at 08:18
45

Go for it. Use auto anywhere it makes writing code easier.

Every new feature in any language is going to get overused by at least some types of programmers. It is only through moderate overuse by some experienced programmers (not noobs) that the rest of the experienced programmers learn the boundaries of proper use. Extreme overuse is usually bad, but could be good because such overuse may lead to improvements in the feature or a better feature to replace it.

But if I were working on code with more than a few lines like

auto foo = bla();

where the type is indicated zero times, I might want to change those lines to include types. The first example is great since the type is stated once, and auto saves us from having to write messy templated types twice. Hooray for C++++. But explicitly showing the type zero times, if it's not easily visible in a nearby line, makes me nervous, at least in C++ and its immediate successors. For other languages designed to work at a higher level with more abstraction, polymorphism and genericity, it's fine.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
DarenW
  • 16,549
  • 7
  • 63
  • 102
  • 4
    Why do people keep justifying 'auto' with "long type names" when the 'using' statement is to alias long type names? using alias = aVeryLongName – user997112 Sep 26 '20 at 01:31
  • 1
    It makes writing code easier but it makes often reading the code far more difficult. When the code gets longer, the team gets bigger and bigger, with 1 guy to write a line and all others to read it.. Thus, the work of the developer becomes more and more to read the code. – kingsjester Jul 23 '22 at 08:15
  • Why do people try to justify not using auto because they use useless variable and function name. The actual type of a variable is typically less important than the contextual meaning provided by a good name. – Matthew Whited May 16 '23 at 09:40
41

Yes, it can be overused to the detriment of readability. I suggest using it in the contexts where exact types are long, or unutterable, or not important for readability, and variables are short-lived. For example, iterator type usually is long and isn't important, so auto would work:

   for(auto i = container.begin(); i != container.end(); ++i);

auto here doesn't hurt readability.

Another example is parser rule type, which can be long and convoluted. Compare:

   auto spaces = space & space & space;

with

r_and_t<r_and_t<r_char_t<char>&, r_char_t<char>&>, r_char_t<char>&> spaces = 
   space & space & space;

On the other hand, when type is known and is simple, it's much better if it stated explicitly:

int i = foo();

rather than

auto i = foo();
Gene Bushuyev
  • 5,512
  • 20
  • 19
  • 2
    Of course, having a range-based for loop in the language makes your first example less exciting. 8v) – Fred Larson Jun 22 '11 at 05:00
  • @Fred: the type can still be cumbersome (I am thinking associative containers) – Matthieu M. Jun 22 '11 at 06:13
  • If I read your code and I don't know what "space & space & space" mean, auto doesn't help me to understand it. – Dmitriy Jun 22 '11 at 07:21
  • @Matthieu M.: Yes, `auto` is certainly useful for the result of a find algorithm or something. But I'm not sure there's much need for writing a straight iterator loop anymore. – Fred Larson Jun 22 '11 at 15:24
  • 4
    @Fred: Any time your bounds aren't `begin()` and `end()`, or your step size is anything other than one, or you are modifying the container as you loop, the range-based for statement won't help you. – Dennis Zickefoose Jun 22 '11 at 15:32
  • 6
    @geotavros: And `r_and_t&, r_char_t&>, r_char_t&>` does? – Dennis Zickefoose Jun 22 '11 at 15:33
  • @Dennis sure, at least I can search for r_and_t and see what is it – Dmitriy Jun 22 '11 at 15:58
  • 7
    @geotavros: Or you can see what type `space` is, and search for that. That's the more useful information anyhow... after all, the issue is not "what type is this new variable" but rather "what does `space & space & space` mean?" The actual type of the expression is just noise. – Dennis Zickefoose Jun 22 '11 at 17:12
  • @geotavros: you wouldn't want to search for `r_and_t` or any other type of that composite, you might see it when compiler prints error message, and it can be several pages long, and you might be forced to sort that out. But if you just want to read the code to understand what it does, you would look at definition of `space` and the definition of `operator&`. – Gene Bushuyev Jun 22 '11 at 18:30
  • @DennisZickefoose Any time your bounds aren't begin() and end(), or your step size is anything other than one, or you are modifying the container as you loop, you should probably use or make an algorithm. – R. Martinho Fernandes Oct 01 '13 at 21:54
24

auto can be very dangerous in combination with expression templates which are used a lot by linear algebra libraries such as Eigen or OpenCV.

auto A = Matrix(...);
auto B = Matrix(...);
auto C = A * B; // C is not a matrix. It is a matrix EXPRESSION.
cout << C; // The expression is evaluated and gives the expected result.
... // <code modifying A or B>
cout << C; // The expression is evaluated AGAIN and gives a DIFFERENT result.

Bugs caused by this type of mistakes are a major pain to debug. One possible remedy is to explicitly cast the result to the expected type if you are hellbent on using auto for the left-to-right declaration style.

auto C = Matrix(A * B); // The expression is now evaluated immediately.
morotspaj
  • 1,400
  • 11
  • 26
  • 1
    That seems like strange behavior to begin with. If I'm multiplying two matrices, even if the operation is lazy, I wouldn't expect it to be re-evaluatable, I'd expect it to maintain its evaluated state after the initial evaluation. If you want to change the parameters without modifying the original parameters, wouldn't you end up having to rebuild the expression anyway? Or is it designed for a streaming-processing sort of situation, where the original parameters are constantly changing but the procedure remains the same? – JAB Nov 13 '15 at 19:10
  • 1
    Whether or not the `A*B` expression is copied in an `auto` variable or something else, the behavior you describe is still present. – xtofl Jan 20 '16 at 09:52
  • No bug is *caused* by using `auto`. – Jim Balter Jan 26 '17 at 01:36
  • @JAB: It's designed to support simplifications and synergies between operations, for example `diag(A * B)` doesn't have to waste cycles computing the off-diagonal elements. – Ben Voigt Feb 12 '18 at 06:23
  • 2
    I have also spotted code like 'for (auto o : vecContainer)' where 'o' was a heavy object which gets copied every time. My recommendation would be to use it for what it was originally intended, that is templates (with difficult deduction guidelines) and laborious typedef's. Even then you have to be careful and distinct between auto and auto&. – gast128 Jan 19 '20 at 12:55
  • anybody who worked on real longterm large scale projects understands what you say very well, debugging code with auto, is nightmare from the pits of hell.. – user2645752 Jan 11 '22 at 07:34
10

I use auto wihout restriction and didn't face any problem. I even sometimes end up using it for simple types like int. This makes c++ a higher level language for me, and allows to declare variable in c++ like in python. After writing python code, I even sometimes write e.g.

auto i = MyClass();

instead of

MyClass i;

This is one case where I would say it is an abuse of the auto keyword.

Often I don't mind what is the exact type of the object, I'm more interested in its fonctionality, and as function names generally say something about the objects they return, auto does not hurt: in e.g. auto s = mycollection.size(), I can guess that s will be a kind of integer, and in the rare case where I care about the exact type, let's check the function prototype then (I mean, I prefer to have to check when I need the info, rather than a priori when code is written, just in case it would be usefull someday, as in int_type s = mycollection.size()).

Concerning this example from the accepted answer:

for ( auto x = max_size; x > 0; --x )

In my code I still use auto in this case, and if I want x to be unsigned, then I use an utility function, named say make_unsigned, which expresses clearly my concerns:

for ( auto x = make_unsigned(max_size); x > 0; --x )

disclaimer: I just describe my use, I'm not competent to give advices!

rafak
  • 5,501
  • 2
  • 19
  • 30
  • 1
    @ChristianRau: wasn't sarcastic. Note that I didn't recommend the use `auto i = MyClass()`. – rafak Jun 15 '13 at 12:12
  • 3
    Follow-up: see: http://herbsutter.com/2013/06/13/gotw-93-solution-auto-variables-part-2/. The use of e.g. `as_unsigned` is recommended there, or even `auto w = widget{};`. – rafak Jun 15 '13 at 12:16
3

One of the major problem with C++ program is it allows you to use the uninitialized variable. This leads us to nasty non deterministic program behavior. It should be noted that modern compiler now throw appropriate/message warning messages if program tires to use it.

Just to illustrate this, consider below c++ program:

int main() {
    int x;
    int y = 0;
    y += x;
}

If I compile this program using modern compiler(GCC), it gives the warning. Such warning may not be very obvious if we are working with the real complex production code.

main.cpp: In function 'int main()':

main.cpp:4:8: warning: 'x' is used uninitialized in this function [-Wuninitialized]

y += x;

    ^

================================================================================= Now if we change our program which uses auto, then compile we get the following:

int main() {
    auto x;
    auto y = 0;
    y += x;
}

main.cpp: In function 'int main()':

main.cpp:2:10: error: declaration of 'auto x' has no initializer

 auto x;

      ^

With auto, it is not possible to use the uninitialized variable. This is major advantage which we may get(for free), if we start using auto.

This concept and other great great modern C++ concept is explained by C++ expert Herb Shutter in his CppCon14 talk:

Back to the Basics! Essentials of Modern C++ Style

Mantosh Kumar
  • 5,659
  • 3
  • 24
  • 48
  • 2
    Yes. And to specify the type you can initialise as 0i, 0u, 0l, 0ul, 0.0f, 0.0, or even int(), unsigned(), double(), etc. – Robinson Mar 20 '15 at 10:53
  • 7
    This argument is ridiculous. You're saying "you can't forget the initialiser because you'll get a compiler error", but that requires you to remember to use `auto`. – Lightness Races in Orbit Aug 20 '15 at 12:21
  • 1
    @LightnessRacesinOrbit: I realized(learnt) this concept from Herb Sutter talk. I found it logical/practical advice from herb talk, hence thought to share with community. – Mantosh Kumar Aug 20 '15 at 15:55
  • 4
    I don't think this is good motivation to use auto. Just turn on your compiler's warning flag for use of uninitialized variables and address all of the warnings. That's not to say you should _not_ use `auto` - but you don't need it to aboid this issue. – einpoklum Mar 27 '17 at 20:27
2

One danger I have noted is in terms of references. e.g.

MyBigObject& ref_to_big_object= big_object;
auto another_ref = ref_to_big_object; // ?

The problem is another_ref is not actually a reference in this case it is MyBigObject instead of MyBigObject&. You end up copying a big object without realising it.

If you are getting a reference directly from a method you might not think about what it actually is.

auto another_ref = function_returning_ref_to_big_object();

you would need "auto&" or "const auto&"

MyBigObject& ref_to_big_object= big_object;
auto& another_ref = ref_to_big_object;
const auto& yet_another_ref = function_returning_ref_to_big_object();
user2495422
  • 101
  • 1
2

TL;DR: See rule-of-thumb at the bottom.

The accepted answer suggests the following rule of thumb:

Use auto whenever it's hard to say how to write the type at first sight, but the type of the right hand side of an expression is obvious.

But I would say that's too restrictive. Sometime I don't care about the types, since the statement is informative enough without me bothering to take the time to figure the type out. What do I mean by that? Consider the example which has popped up in some of the answers:

auto x = f();

What makes this an example of misuse of auto? Is it my ignorance of f()'s return type? Well, it may indeed help if I did know it, but - that's not my main concern. What is much more of a problem is that x and f() are pretty meaningless. If we had:

auto nugget = mine_gold();

instead, then I usually don't care whether the return type of the function is obvious or not. Reading the statement, I know what I'm doing and I know enough about what the return value's semantics to not feel I need to also know its type.

So my answer is: Use auto whenever the compiler allows it, unless:

  • You feel the variable name together with the initialization / assignment expression do not provide enough information about what the statement is doing.
  • You feel the variable name together with the initialization / assignment expression provides "misleading" information about what the type should be - i.e., if you had to guess what comes instead of the auto you would be able to make a guess - and it would be wrong, and this false assumption has repercussions later in the code.
  • You want to force a different type (e.g. a reference).

And also:

  • Prefer giving a meaningful name (which does not contain the type name of course) before replacing auto with the concrete type.
einpoklum
  • 118,144
  • 57
  • 340
  • 684
1

Use auto where it makes sense for a type to be inferred. If you have something that you know is an integer, or you know it's a string, just use int / std::string, etc. I wouldn't worry about "overusing" a language feature unless it gets to the point of ridiculousness, or obfuscates code.

That's my opinion anyway.

LainIwakura
  • 2,871
  • 2
  • 19
  • 22
1

What auto does?

It tells compiler to infer(determine) the variable's data type based on its initialized value. It uses type deduction.

Where should auto be used?

  • When you are not interested in knowing the type of variable and just want to use it.

  • When you want to avoid incredibly long and ugly typenames.

  • When you are not sure of the type himself.

  • When you do not want to see uninitialized variables in your code i.e. auto forces you to initialize a variable hence you can’t forget doing that.

When it should not be used or Cons of auto

  • Referring to its functionality, auto may deduce type incorrectly, One such case is
 std::vector<bool> vec(10, 0);

 auto x = vec[2];

 bool y = vec[2];

 std::cout << typeid(x).name() << "\n";

 std::cout << typeid(y).name() << "\n";

The output on G++ 10.2 is surprising:

St14_Bit_reference

b
  • It should not be used if you want to make your code readable & Understandable for other people. It hides the data type visibility from the reader.
TonyParker
  • 2,024
  • 5
  • 18
  • 27
0

auto keyword can only be used for local variable, not to arguments or class/struct members. So, it is safe and viable to use them anywhere you like. I do use them a lot. The type is deduced at compile time, the debugger shows the type while debugging, the sizeof reports it correctly, the decltype would give correct type - there is no harm. I don't count auto as overused, ever!

Ajay
  • 18,086
  • 12
  • 59
  • 105
  • auto can be used as function parameter as well. https://en.cppreference.com/w/cpp/language/auto Furthermore, auto and type-constraint auto (since C++20) can appear in: the parameter declaration of a lambda expression: [](auto&&){}. Such lambda expression is a generic lambda. (since C++20) a function parameter declaration: void f(auto);. The function declaration introduces an abbreviated function template. – buddy Jan 02 '21 at 02:37
-6

One of my bitter experience with auto is using it with lambda expressions:

auto i = []() { return 0; };
cout<<"i = "<<i<<endl; // output: 1 !!!

Actually, here i is resolved to function pointer of int(*)(). This is just a simple cout, but just imagine what kind of bad compilation / runtime errors it can cause when used with template.

You should avoid auto with such expressions and put a proper return type (or controlled decltype())

Correct usage for above example would be,

auto i = []() { return 0; }(); // and now i contains the result of calling the lambda  
Francesco
  • 3,200
  • 1
  • 34
  • 46
iammilind
  • 68,093
  • 33
  • 169
  • 336
  • Why use a lambda if you call it immediately and then it's discard it? – R. Martinho Fernandes Jun 22 '11 at 05:13
  • 7
    You did a terrible job of explaining what that has to do with auto. You created a function and then printed it... Okay? – Dennis Zickefoose Jun 22 '11 at 05:24
  • @Dennis, this is an example to demo that what happens if the `()` are missed in the lambda expression. It's not a real program. – iammilind Jun 22 '11 at 05:26
  • 5
    @iammilind: and what does that have to do with auto? – R. Martinho Fernandes Jun 22 '11 at 05:33
  • 1
    @Martinho, Had `i` been declared as `int`, the error would have been caught at compile time (if it was intended as `int`). It's likely that one might forget to put `()` in the end of lambda expression which will evaluate it to a function pointer. I personally found it hard to debug when I started learning C++0x. – iammilind Jun 22 '11 at 05:38
  • 7
    I find it highly unlikely that one would want to put `()` in the end. Lambdas are there to act as functions and that's where the function pointer conversion comes from. If you want to call it straight away, why use a lambda at all? `auto i = 0;` works rather well. – R. Martinho Fernandes Jun 22 '11 at 05:46
  • @Martinho, I don't know why you are taking the example literally ? If there were more amount of code (with `-> ` inside the lambda, still my example will be true. I don't need to write big program to demo something. – iammilind Jun 22 '11 at 05:58
  • 4
    Can you at least describe a scenario where `auto x = []() { /* .... whatever goes in here ... */ }()` is better than `auto x = /* .... whatever goes in here ... */;`, i.e, the same thing, without the lambda? I find that rather pointless, for the same reason `auto x = 42 + y - 42` is pointless. – R. Martinho Fernandes Jun 22 '11 at 06:03
  • 1
    I'm not saying this is a bad example, I'm saying you did a bad job of explaining why it was a mistake. At no point do you say what you wanted to happen... and the trivialness of the example makes it very non-obvious that a mistake happened at all. For the record, I agree that long term, this is going to be a *huge* source of errors. – Dennis Zickefoose Jun 22 '11 at 06:48
  • 1
    @Martinho: Consider a variation on the construct here: http://stackoverflow.com/q/6077718/293791 where the loop is calculating some value which then gets `return`ed. – Dennis Zickefoose Jun 22 '11 at 15:47
  • 7
    -1 this is not auto's fault. The type of a lambda can't be spelled so auto is ***required***, if you forget to *call* the function then that's your own lookout! You could put an un-called function pointer into a C printf just as haphazardly. – spraff Sep 20 '11 at 11:04
  • @spraff, if I am not using `auto` keyword then compiler will give an error. I was just showing the *possibility* for drawback of **automatic type deduction**. Mind that most of the programming errors are **programmer's lookouts**; but we still criticize the language. – iammilind Sep 20 '11 at 11:10
  • 1
    @R.MartinhoFernandes not that I agree with this answer, but a suitable reason to evaluate a lambda immediately after declaring it is for complicated (multi-line) initialization of a `const` variable. Without a lambda you would either need a builder function declared elsewhere (and lose locality of reference), or you'd need to make the variable non-const and perform the initialization in multiple steps / lines. Lambdas are an excellent choice for such a one-off initialization function that might as well exist locally. – YoungJohn Sep 11 '15 at 19:00