Analysis of C ++ auto type specifiers
When programming, you often need to assign the expression value to the variable, which requires you to clearly know the type of the expression when declaring the variable. However, it is not that easy to do this, and sometimes it cannot even be done at all. To solve this problem, the C ++ 11 standard has been introducedauto
Type specifier, which enables the compiler to analyze the type of the expression for us.
Different from the original specifiers that only correspond to a specific type,auto
Let the compiler calculate the variable type through the initial value. Apparently,auto
The defined variable must have an initial value.
Useauto
It has the following benefits:
Reliability: It can also work if the expression type is changed (including when the function return value is changed.
Performance: Make sure that the conversion is not performed.
Availability: You do not have to worry about spelling difficulties and misspelling of the type name.
Efficiency: Code becomes more efficient.
Auto item = val1 + val2; // The result of adding val1 and val2 shows that the item Type auto I = 0, * p = & I; // I is an integer, p is an integer pointer.
Useauto
Multiple variables can be declared in one statement. However, a declaration statement can only have one basic data type. Therefore, the initial basic data types of all variables in the statement must be consistent:
auto sz = 0, pi = 3.14; // Error!
The compiler deducedauto
Sometimes the type is not exactly the same as the initial value type. The compiler will change the result type appropriately to make it more compliant with the initialization rules, for example:
Use
auto
Will delete the reference
int count = 10;int& countRef = count;auto myAuto = countRef;countRef = 11;cout << count << " "; // print 11myAuto = 12;cout << count << endl; // print 11
You may thinkmyAuto
Isint
But it is not. It is justint
Because the output is11 11
Instead11 12
Ifauto
The reference has not been deleted.
const
Qualifier
First, introduce a statement:
Top layerconst
Indicates that the pointer itself is a constant,
Bottom Layerconst
Indicates that the object referred to by the pointer is a constant. Average
auto
The top layer is ignored.
const
At the same time, the underlying
const
It will be retained, for example:
Int I = 0; const int ci = I, & cr = ci; auto B = ci; // B is an integer (the top-level const feature of ci is ignored) auto c = cr; // c is an integer (cr is the alias of ci, ci itself is a top-level const) auto d = & I; // d is an integer pointer (the integer address is the pointer to an integer) auto e = & ci; // e is a pointer to an integer constant (the constant object address is a kind of underlying const)
If you want to deduceauto
Type is a top layerconst
, It should be clearly pointed out:
Const auto f = ci; // The deduction type of ci is int, and f is const int.
You can also set the referenced typeauto
In this case, the original initialization rules still apply:
Auto & g = ci; // g is an integer constant reference, bound to ciauto & h = 42; // Error: the const auto & j = 42; // OK cannot be bound to a constant reference.
Remember, symbol*
And&
Only a part of a declaration, not a part of the basic data type, so the initial value must be of the same type:
Auto k = ci, & l = I; // k is an integer. l is an integer that references auto & m = ci, * p = & ci; // m is a reference to an integer constant. p is the pointer to an integer constant. auto & n = I, * p2 = & ci; // Error: the type of I is int, the & ci type is const int
Add more sample code:
The following statement is equivalent. In the first statement
j
Declared as type
int
. In the second statement
k
Deduced as 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 statement is equivalent, but the second statement is simpler than the first statement. Use
auto
One of the most convincing reasons for the keyword is simplicity.
map
>::iterator i = m.begin(); auto i = m.begin();
Use
iter
And
elem
When a loop is started
#include
using namespace std;int main(){ deque
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 { /* ... */ }}
Use the following code snippet
new
Operators and pointer declarations to declare pointers
double x = 12.34;auto *y = new auto(x), **z = new auto(&x);
The next code snippet declares multiple symbols in each declaration statement. Note that all symbols in each statement are resolved 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 snippet uses conditional operators (
?:
) Change the variable
x
Declared as value:
200
Integer:
int v1 = 100, v2 = 200;auto x = v1 > v2 ? v1 : v2;
The following code snippet adds the variable
x
Initialize to type
int
, Set the variable
y
Initialize the object type
const int
To change the variable
fp
Initialize to the return type
int
Pointer to the function.
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; //...}