Visible to Intel only — GUID: GUID-B881E6C9-F10E-4AD6-9D93-26D71ED2DBCB
Visible to Intel only — GUID: GUID-B881E6C9-F10E-4AD6-9D93-26D71ED2DBCB
Type Inference in C++ (auto and decltype)
This chapter covers type inference. You will learn:
What is type reference in C++?
How should the keywords auto and decltype be used?
What are the differences between auto and decltype?
Introduction
Type inference refers to the automatic deduction of the data type of an expression in a programming language. Since C++11, many keywords were included that allow type inference to be left to the compiler. Before C++11, each data type needed to be explicitly declared at compile time. Now, using type inference, we can avoid wasting time writing out things that the compiler already knows or can deduce. As all the types are deduced in the compiler phase only, the compilation time increases slightly; at the same time, it doesn't affect the runtime of the created program. In C++, two keywords are introduced for type inference:
auto keyword
decltype type specifier
auto Keyword
The auto keyword indicates the type of declared variable to be deduced automatically from its initializer. If the return type of a function is auto, it will be evaluated at runtime by the returned type expression. It's important to note that the variable declared with the auto keyword needs to be initialized at declaration time. Otherwise, a compilation error occurs. Let's see an example of auto usage:
#include <iostream>
#include <typeinfo>
int main(){
auto x = 1;
auto y = 3.7;
// checking type of declared variables
std::cout << typeid(x).name() << '\n';
std::cout << typeid(y).name() << '\n';
return 0;
}
The output of the code above is:
i
d
This means that variable x is type of int when variable y is type of double. Using auto helps avoid long initializations (e.g., when creating iterators for containers).
decltype Type Specifier
The decltype specifier inspects the declared type of an entity or the type of an expression. We can say that decltype is more like an operator that evaluates the type of passed expression.
When you use auto, you declare a variable with a particular type, but when using decltype you extract the type from the variable. Let's see an example of decltype usage:
#include <iostream>
#include <typeinfo>
int foo() { return 13; }
int main(){
// x has the same type as a type returned by foo function
decltype(foo()) x;
// checking type of x
std::cout << typeid(x).name();
return 0;
}
The output of this code is:
i
This means that variable x is type int.
Now, let's see an example using both auto and decltype:
#include <iostream>
#include <vector>
int main(){
std::vector<int> vec(10);
// using auto for type deduction
for(auto i = vec.begin(); i < vec.end(); i++){
std::cin >> *i;
}
// using decltype for type deduction
for(decltype(vec.begin()) i = vec.begin(); i < vec.end(); i++){
std::cin >> *i;
}
return 0;
}
In this example, we are using auto and decltype for the same purpose — deduction of the iterator type.
Summary
It's important to understand that auto and decltype serve different purposes, so they are not exactly the same. auto is used for automatic type deduction whereas decltype yields the type of a specified expression. Unlike auto, which deduces types based on values being assigned to the variable, decltype deduces the type from an expression passed to it.