Tóm Tắt
auto
(C++)
In this article
Deduces the type of a declared variable from its initialization expression.
Note
The C++ standard defines an original and a revised meaning for this keyword. Before Visual Studio 2010, the auto
keyword declares a variable in the automatic storage class; that is, a variable that has a local lifetime. Starting with Visual Studio 2010, the auto
keyword declares a variable whose type is deduced from the initialization expression in its declaration. The /Zc:auto[-]
compiler option controls the meaning of the auto
keyword.
Syntax
auto
declarator initializer;
[](auto
param1, auto
param2) {};
Remarks
The auto
keyword directs the compiler to use the initialization expression of a declared variable, or lambda expression parameter, to deduce its type.
We recommend that you use the auto
keyword for most situations—unless you really want a conversion—because it provides these benefits:
-
Robustness: If the expression’s type is changed—including when a function return type is changed—it just works.
-
Performance: You’re guaranteed that there’s no conversion.
-
Usability: You don’t have to worry about type name spelling difficulties and typos.
-
Efficiency: Your coding can be more efficient.
Conversion cases in which you might not want to use auto
:
-
You want a specific type and nothing else will do.
-
In expression template helper types—for example,
(valarray+valarray)
.
To use the auto
keyword, use it instead of a type to declare a variable, and specify an initialization expression. In addition, you can modify the auto
keyword by using specifiers and declarators such as const
, volatile
, pointer (*
), reference (&
), and rvalue reference (&&
). The compiler evaluates the initialization expression and then uses that information to deduce the type of the variable.
The auto
initialization expression can take several forms:
- Universal initialization syntax, such as
auto a { 42 };
. - Assignment syntax, such as
auto b = 0;
. - Universal assignment syntax, which combines the two previous forms, such as
auto c = { 3.14156 };
. - Direct initialization, or constructor-style syntax, such as
auto d( 1.41421f );
.
For more information, see Initializers and the code examples later in this document.
When auto
is used to declare the loop parameter in a range-based for
statement, it uses a different initialization syntax, for example for (auto& i : iterable) do_action(i);
. For more information, see Range-based for
Statement (C++).
The auto
keyword is a placeholder for a type, but it isn’t itself a type. Therefore, the auto
keyword can’t be used in casts or operators such as sizeof
and (for C++/CLI) typeid
.
Usefulness
The auto
keyword is a simple way to declare a variable that has a complicated type. For example, you can use auto
to declare a variable where the initialization expression involves templates, pointers to functions, or pointers to members.
You can also use auto
to declare and initialize a variable to a lambda expression. You can’t declare the type of the variable yourself because the type of a lambda expression is known only to the compiler. For more information, see Examples of Lambda Expressions.
Trailing Return Types
You can use auto
, together with the decltype
type specifier, to help write template libraries. Use auto
and decltype
to declare a function template whose return type depends on the types of its template arguments. Or, use auto
and decltype
to declare a function template that wraps a call to another function, and then returns whatever is the return type of that other function. For more information, see decltype
.
References and cv-qualifiers
Using auto
drops references, const
qualifiers, and volatile
qualifiers. Consider the following example:
// cl.exe /analyze /EHsc /W4
#include <iostream>
using namespace std;
int main( )
{
int count = 10;
int& countRef = count;
auto myAuto = countRef;
countRef = 11;
cout << count << " ";
myAuto = 12;
cout << count << endl;
}
In the previous example, myAuto is an int
, not an int
reference, so the output is 11 11
, not 11 12
as would be the case if the reference qualifier hadn’t been dropped by auto
.
Type deduction with braced initializers (C++14)
The following code example shows how to initialize an auto
variable using braces. Note the difference between B and C and between A and E.
#include <initializer_list>
int main()
{
// std::initializer_list<int>
auto A = { 1, 2 };
// std::initializer_list<int>
auto B = { 3 };
// int
auto C{ 4 };
// C3535: cannot deduce type for 'auto' from initializer list'
auto D = { 5, 6.7 };
// C3518 in a direct-list-initialization context the type for 'auto'
// can only be deduced from a single initializer expression
auto E{ 8, 9 };
return 0;
}
Restrictions and error messages
The following table lists the restrictions on the use of the auto
keyword, and the corresponding diagnostic error message that the compiler emits.
Error number
Description
C3530
The auto
keyword can’t be combined with any other type-specifier.
C3531
A symbol that is declared with the auto
keyword must have an initializer.
C3532
You incorrectly used the auto
keyword to declare a type. For example, you declared a method return type or an array.
C3533, C3539
A parameter or template argument can’t be declared with the auto
keyword.
C3535
A method or template parameter can’t be declared with the auto
keyword.
C3536
A symbol can’t be used before it’s initialized. In practice, it means that a variable can’t be used to initialize itself.
C3537
You can’t cast to a type that is declared with the auto
keyword.
C3538
All the symbols in a declarator list that is declared with the auto
keyword must resolve to the same type. For more information, see Declarations and Definitions.
C3540, C3541
The sizeof and typeid operators can’t be applied to a symbol that is declared with the auto
keyword.
Examples
These code fragments illustrate some of the ways in which the auto
keyword can be used.
The following declarations are equivalent. In the first statement, variable j
is declared to be type int
. In the second statement, variable k
is deduced to be type int
because the initialization expression (0) is an integer.
int j = 0; // Variable j is explicitly type int.
auto k = 0; // Variable k is implicitly type int because 0 is an integer.
The following declarations are equivalent, but the second declaration is simpler than the first. One of the most compelling reasons to use the auto
keyword is simplicity.
map<int,list<string>>::iterator i = m.begin();
auto i = m.begin();
The following code fragment declares the type of variables iter
and elem
when the for
and range for
loops start.
// cl /EHsc /nologo /W4
#include <deque>
using namespace std;
int main()
{
deque<double> dqDoubleData(10, 0.1);
for (auto iter = dqDoubleData.begin(); iter != dqDoubleData.end(); ++iter)
{ /* ... */ }
// prefer range-for loops with the following information in mind
// (this applies to any range-for with auto, not just deque)
for (auto elem : dqDoubleData) // COPIES elements, not much better than the previous examples
{ /* ... */ }
for (auto& elem : dqDoubleData) // observes and/or modifies elements IN-PLACE
{ /* ... */ }
for (const auto& elem : dqDoubleData) // observes elements IN-PLACE
{ /* ... */ }
}
The following code fragment uses the new
operator and pointer declaration to declare pointers.
double x = 12.34;
auto *y = new auto(x), **z = new auto(&x);
The next code fragment declares multiple symbols in each declaration statement. Notice that all of the symbols in each statement resolve to the same type.
auto x = 1, *y = &x, **z = &y; // Resolves to int.
auto a(2.01), *b (&a); // Resolves to double.
auto c = 'a', *d(&c); // Resolves to char.
auto m = 1, &n = m; // Resolves to int.
This code fragment uses the conditional operator (?:
) to declare variable x
as an integer that has a value of 200:
int v1 = 100, v2 = 200;
auto x = v1 > v2 ? v1 : v2;
The following code fragment initializes variable x
to type int
, variable y
to a reference to type const int
, and variable fp
to a pointer to a function that returns type int
.
int f(int x) { return x; }
int main()
{
auto x = f(0);
const auto& y = f(1);
int (*p)(int x);
p = f;
auto fp = p;
//...
}
See also
Keywords
/Zc:auto
(Deduce variable type)
sizeof
operator
typeid
operator new
Declarations and definitions
Examples of lambda expressions
Initializers
decltype