Prior to the modern C++, the C++ language has a keyword named auto that is used to explicitly specify that the variable should have automatic duration. The automatic duration that adheres to the variable will create the variable at the point of definition (and initialized, if relevant) and destroy the variable when the block they are defined in is exited. For instance, the local variable will be created when it is defined at the beginning of the function and destroyed when the program exits the function where the local variable is there.
Since C++11, the auto keyword is used to tell the compiler to deduce the actual type of a variable that is being declared from its initializer. And since C++14, the keyword can also be applied to a function to specify the return type of the function that is a trailing return type. Now, in modern C++, the use of the auto keyword to specify the automatic duration is abolished since all variables are set to automatic duration by default.
The following is an auto.cpp code demonstrating the use of the auto keyword in the variables. We will define four variables with the auto keyword, and then find out the data type for each variable using the typeid() function. Let's take a look:
/* auto.cpp */
#include <iostream>
#include <typeinfo>
int main()
{
std::cout << "[auto.cpp]" << std::endl;
// Creating several auto-type variables
auto a = 1;
auto b = 1.0;
auto c = a + b;
auto d = {b, c};
// Displaying the preceding variables' type
std::cout << "type of a: " << typeid(a).name() << std::endl;
std::cout << "type of b: " << typeid(b).name() << std::endl;
std::cout << "type of c: " << typeid(c).name() << std::endl;
std::cout << "type of d: " << typeid(d).name() << std::endl;
return 0;
}
As we can see in the preceding code, we have an a variable that will store the integer value and have a b variable that will store the double value. We calculate the addition of a and b and store the result in variable c. Here, we expect that c will store the double object since we add the integer and double object. The last is the d variable that will store the initializer_list<double> data type. When we run the preceding code, we will see the following output on the console:
As can be seen in the preceding snapshot, we are just given the first character of the data type, such as i for integer, d for double, and St16initializer_listIdE for initializer_list<double>, that is the last lowercase d character that stands for double.
We may have to enable the Run-Time Type Information (RTTI) feature in our compiler options to retrieve the data type object. However, GCC has enabled the feature by default. Also, the output of the use of the typeid() function depends on the compiler. We may get the raw type name or just a symbol as we did in the preceding example.
Besides, for variable, as we discussed earlier, the auto keyword can also be applied to a function to deduce a function's return type automatically. Suppose we have the following trivial function named add() to calculate the addition of two parameters:
int add(int i, int j)
{
return i + j;
}
We can refactor the preceding method to use the auto keyword, as we can see in the following lines of code:
auto add(int i, int j)
{
return i + j;
}
Similar to the auto-type variable, the compiler can decide the correct return type based on the returned value of the function. And, as shown in the preceding code, the function will indeed return the integer value since we just add two integer values.
Another feature that uses the auto keyword in modern C++ is trailing the return type syntax. By using this feature, we can specify the return type, the rest of the function prototype, or function signature. From the preceding code, we can refactor it to use the feature as follows:
auto add(int i, int j) -> int
{
return i + j;
}
You might ask me why we have to specify the data type again after the arrow symbol (->), even though we have used the auto keyword. We will find the answer when we cover the decltype keyword in the next section. Also, by using this feature, we can now refactor the preceding auto.cpp code a little bit by modifying the syntax of the main() method, instead of the following syntax of main() function signature:
int main()
{
// The body of the function
}
We can change the signature syntax into the following line of code:
auto main -> int
{
// The body of the function
}
Now, we will see all of our code in this book using this trailing return type feature to apply the modern C++ syntax.