S.4.8 — The auto keyword

Auto prior to C++11

Prior to C++11, the auto keyword was probably the least used keyword in C++. In lesson 4.1a -- Local variables and local scope, you learned that local variables have automatic duration (they’re created at the point of definition, and destroyed when the block they are part of is exited).

The auto keyword was a way to explicitly specify that a variable should have automatic duration:

However, since all variables in modern C++ default to automatic duration unless otherwise specified, the auto keyword was superfluous, and thus obsolete.

Type inference in C++11

In C++11, the meaning of the auto keyword has changed, and it is now a useful addition to your C++ vocabulary.

Consider the following statement:

If C++ already knows 5.0 is a double literal, why do we have to explicitly specify that d is actually a double? Wouldn’t it be nice if we could tell a variable to just assume the proper type based on the value we’re initializing it with?

Starting with C++11, the auto keyword does just that. When initializing a variable, the auto keyword can be used in place of the variable type to tell the compiler to infer the variable’s type from the initializer’s type. This is called type inference (also sometimes called type deduction).

For example:

This even works with the return values from functions:

Note that this only works when initializing a variable upon creation. Variables created without initialization values can not use this feature (as C++ has no context from which to deduce the type).

While using auto in place of fundamental data types only saves a few (if any) keystrokes, in future lessons we will see examples where the types get complex and lengthy. In those cases, using auto can be very nice.

The auto keyword can’t be used with function parameters

Many new programmers try something like this:

This won’t work, because the compiler can’t infer types for function parameters x and y at compile time.

If you’re looking to create functions that work with a variety of different types, you should be using function templates, not type inference. This restriction may be lifted in future versions of C++ (with auto acting as a shorthand way to create function templates), but as of C++14 this is not supported. The one exception is for lambda expressions, which is an advanced C++ topic.

Type inference for functions in C++14

In C++14, the auto keyword was extended to be able to auto-deduce a function’s return type. Consider:

Since x + y evaluates to an integer, the compiler will deduce this function should have a return type of int.

While this may seem neat, we recommend that this syntax be avoided for functions. The return type of a function is of great use in helping to document for the caller what a function is expected to return. When a specific type isn’t specified, the caller may misinterpret what type the function will return, which can lead to inadvertent errors.

Interested readers may wonder why using auto when initializing variables is okay, but not recommended for function return types. A good rule of thumb is that auto is okay to use when defining a variable, because the object the variable is inferring a type from is right there, on the right side of the statement. However, with functions, that is not the case -- there’s no context to help indicate what type the function returns. A user would actually have to dig into the function body itself to determine what type the function returned. It’s much less intuitive, and therefore more error prone.

Trailing return type syntax in C++11

C++11 also added the ability to use a trailing return syntax, where the return type is specified after the rest of the function prototype.

Consider the following function declaration:

In C++11, this could be equivalently written as:

In this case, auto does not perform type inference -- it is just part of the syntax to use a trailing return type.

Why would you want to use this?

One nice thing is that it makes all of your function names line up:

But it is of more use when combined with some advanced C++ features, such as classes and the decltype keyword. We’ll talk more about the other auto uses when we cover the decltype keyword.

For now, we recommend the continued use of the traditional function return syntax.


Starting with C++11, the auto keyword can be used in place of a variable’s type when doing an initialization in order to perform type inference.

Auto is best used when the object’s type is hard to type, but the type is obvious from the right hand side of the expression.

Other uses of the auto keyword should generally be avoided except on an as-needed basis.

S.4.x -- Chapter 4 comprehensive quiz
S.4.7 -- Structs

56 comments to S.4.8 — The auto keyword

  • Fernando


    1) Is there any performance-wise drawback for using "auto"?

    2) You mentioned that the compiler might guess your variable type wrong (not using these words though, and correct me if I'm wrong). Does this mean that duck-typed programming languages like Python suffer from this drawback by design?


    • Alex

      1) No.
      2) The compiler won't guess it wrong. However, if you use auto as a function return value, the caller of the function might get it wrong. This could cause any number of problems to manifest, possibly resulting in incorrect or undefined behavior.

  • Edwin Martens

    auto is evil !
    why ?

    auto value = doSomethingWith(int x);

    The compiler may see the type of value, BUT YOU DO NOT !!!

    what type is value here ?, anyone ?

    • Alex

      Auto isn't evil, it just needs to be used appropriately.

      Your example would be a misuse, as it gives no context as to what type of return value to expect. But something like:

      is fine -- it's clear we're returning some kind of Dictionary object.

      A good rule of thumb is: "Use auto when it's hard to write the type, but the type is obvious".

  • Anthony

    I've been using the auto keyword quite freely. But I can't figure out what the actual type is in this example:

    • I can't reproduce your error. Please post a minimal example that causes the error.

      • Anthony

        Not sure what you mean. Should I post a minimal compilable version?

        Btw, when I hover over 'begin' in both MSVC AND VSCode, it says 'container<char>::iterator' and I'm very surprised this isn't correct.

        • It is `container<char>::iterator`. There's something else wrong in your code.

          > Should I post a minimal compilable version?
          "compilable" is going to be hard, because your code doesn't compile. Post a minimal version that causes your error and no other errors.

          • Anthony


            Finally returned to this problem. As previously stated, @auto works, but when I attempt to do it 'manually', I get an error. Here's code showing the problem:


    When will you start advance c++ topics. I really need it.

  • Perhaps I'm a bit early, but I am really wondering if auto makes my life easier.

    I do see the sense in Go where auto is not needed

    I could see the sense if something like this were possible:

    Well, I guess not... but maybe I am just getting ahead of things.

    (BTW. Just to note... This is the 6th C++ tutorial I've seen, but the first one in which a simple "Hello World" example didn't give me compile errors, already, and this tutorial made me write the first C++ code that actually WORKS. I always felt silly that I've been coding for almost 35 years and I could never master C and C++, so thanks a lot). ;)

    • Snippet 1
      * Line 1, 2, 4: Initialize your variables with brace initializers. You used copy initialization.

      @auto comes in handy when you get to templates. Types can fill up entire lines

  • Gurdeep Singh

    [auto calculateThis(int x, double d) -> std::string;] How it evauluates to std::string. Should'nt it be double?

    • Hi!

      Without knowing what @calculateThis does, it could return anything. Judging by the function's name, you're right, it should most likely return an int or double.

      • Alex

        The trailing return type syntax moves the return type from before the function name to after the function name.

        "auto calculateThis(int x, double d) -> std::string" clearly returns a std::string (as the "-> std::string" part of the declaration indicates).

        auto in this context doesn't perform type inference in this context, it just acts as a placeholder.

  • magaji::hussaini

    I am not in love with this "auto" keyword to be used for variables either, makes me kinda lazy not to even care about my variable type just like dynamically typed languages cant even use unsigned types, and I think it increases compilation time also

  • Pabitra Padhy

    Hey Alex,

    Although Type Inference could be applied to members of struct or class
    we have to make them static and const, then we could initialize them.

    I don't see any use for this.
    Could you care to explain, what could be the uses for such an use of Type Inference ?

  • Blaqsmite

    hi Alex
    Am I doing something wrong or is ok to say that auto cant be used to define a variable in a .h file?
    I am attempting to do this in visual studio 2017 which i am guessing uses vc2015. I dont what version of Cpp it uses.
    great tutorials by the way

    • nascardriver

      Hi Balqsmite!

      auto can be used in header files just fine, without code I'm guessing you're not initializing the variable in which case there's no way for your compiler to know which data type it should be.

  • himanshu shivnani

    The article is very useful Alex. Keep it up!!

  • vd

    Precise and well written. Thank you for this tutorial!

  • antiriad7

    Why did u write &x and &y and not x and y in function parameters?

  • Peter

    > This is called automatic type deduction.

    Actually AFAIK it's simply called type inference -

  • Zachary Fojtasek

    Why can I not do something like this?:

    this does not compile.

    But if it did, I could use a function like this instead of overloading functions.

    • Alex

      Auto tells the compiler to infer the proper type -- because the compiler does the inferring, the type has to be inferable at compile-time. Your example doesn't work because x and y (and the thus the return type) can't be determined at compile time.

      However, C++ does provide functionality to do what you want. In chapter 13 I talk about function templates, which are designed to do exactly what you're intending here.

      (Note that this restriction may be lifted in future versions of C++)

  • selami

    auto keyword can easily be used by int, double, char etc.. but not used with string.
    why? when used. it is written as PKc. what does it mean?

  • Matt

    Can the auto keyword be used for function return type deduction when the return type is void(or as part of the trailing return type syntax)?

  • Matt

    In the first paragraph, the wording needs to be updated to say that local variables are created upon definition(not when entering the block).
    Hope I'm not getting annoying :)

  • Dekasi

    "While this may seem neat, we recommend that this syntax be avoided for functions that return a fixed type. The return type of a function is of great use in helping to document a function. When a specific type isn’t specified, the user may not know what is expected.

    (Side note: Interested readers may wonder why using auto when initializing variables is okay, but not recommended for function return types. A good rule of thumb is that auto is okay to use within the boundaries of a statement, because the type being inferred often doesn’t matter, and if it does, the actual type information is generally at hand. However, across statement boundaries, it’s better for documentation and maintenance to make types explicit.)"

    I don't understand few things in this excerpt:
    1. what are fixed types
    2. to document a function
    3. in which case you think that the user needs to know to type
    4. what can be referred as a boundary of statement
    5. `the type being inferred often doesn’t matter, and if it does, the actual type information is generally at hand`- what you mean with this

    • Alex

      Rather than answer all of these questions, I updated the wording of that section substantially. Have another read and see if it's clearer now. If not, let me know what's still confusing.

  • shreyanshd

    Would the use of automatic type deduction in C++ affect the performance?  If auto keyword is used extensively in C++ then the compiler has to figure out the data type every time, which would degrade performance.

    Correct me if I am wrong.
    Great tutorials. Love them :)

    • Alex

      No, the compiler already needs to know the type in order to do strong type checking (to give you an error if you try to do something nonsensical). Auto is really just a convenience for the programmer.

  • Ola Sh

    Thanks for the good work. In my opinion, this is the best programming tutorial that I have used. Thanks again.

  • Sandro

    "auto d = 5.0; // 5.0 is a double literal, so d will be type double"

    It's a double literal because there is no "f" or "l" at the end of the number?

  • hridayesh

    hey alex i am using codeblocks and this program is throwing error saying that k and l are not declared.

  • programmer, another one

    hello alex,

    I used the auto keyword in a class as a public member on two variables in Qt creator, and the compiler flagged it as an error saying that: "a non-static data member cannot have a type that contains auto".

    do you know why this may have occurred?


  • Yup Boyan is right. Remove "we will" from the following sentence:
    "While using auto in place of fundamental data types only saves a few (if any) keystrokes, in future lessons we’ll we will see examples where the types get complex and lengthy."
    Just highlighting the typo made in this section. :)

  • Boyan

    Just above the "Automatic type deduction for functions in C++14" headline, you've written "we’ll we will see "

    I've got to say though...this is probably the best tutorial I've seen on ANYTHING, let alone C++! Thank you for the awesome work! :)

Leave a Comment

Put all code inside code tags: [code]your code here[/code]