The auto type-specifier signifies that the type of a variable being declared shall be deduced from its initializer or that a function declarator shall include a trailing-return-type.
The auto type-specifier may appear with a function declarator with a trailing-return-type ([dcl.fct]) in any context where such a declarator is valid.
Otherwise, the type of the variable is deduced from its initializer. The name of the variable being declared shall not appear in the initializer expression. This use of auto is allowed when declaring variables in a block ([stmt.block]), in namespace scope ([basic.scope.namespace]), and in a for-init-statement ([stmt.for]). auto shall appear as one of the decl-specifiers in the decl-specifier-seq and the decl-specifier-seq shall be followed by one or more init-declarators, each of which shall have a non-empty initializer.
[ Example:
auto x = 5; // OK: x has type int const auto *v = &x, u = 6; // OK: v has type const int*, u has type const int static auto y = 0.0; // OK: y has type double auto int r; // error: auto is not a storage-class-specifier
— end example ]
The auto type-specifier can also be used in declaring a variable in the condition of a selection statement ([stmt.select]) or an iteration statement ([stmt.iter]), in the type-specifier-seq in the new-type-id or type-id of a new-expression ([expr.new]), in a for-range-declaration, and in declaring a static data member with a brace-or-equal-initializer that appears within the member-specification of a class definition ([class.static.data]).
A program that uses auto in a context not explicitly allowed in this section is ill-formed.
Once the type of a declarator-id has been determined according to [dcl.meaning], the type of the declared variable using the declarator-id is determined from the type of its initializer using the rules for template argument deduction. Let T be the type that has been determined for a variable identifier d. Obtain P from T by replacing the occurrences of auto with either a new invented type template parameter U or, if the initializer is a braced-init-list ([dcl.init.list]), with std::initializer_list<U>. The type deduced for the variable d is then the deduced A determined using the rules of template argument deduction from a function call ([temp.deduct.call]), where P is a function template parameter type and the initializer for d is the corresponding argument. If the deduction fails, the declaration is ill-formed. [ Example:
auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int> auto x2 = { 1, 2.0 }; // error: cannot deduce element type
— end example ]
If the list of declarators contains more than one declarator, the type of each declared variable is determined as described above. If the type deduced for the template parameter U is not the same in each deduction, the program is ill-formed.
[ Example:
const auto &i = expr;
The type of i is the deduced type of the parameter u in the call f(expr) of the following invented function template:
template <class U> void f(const U& u);