Type Inference in C++ (auto and decltype)

 auto keyword:

Automatic deduction of data type of an expression in a programming language is called 'Type Inference'. Each data type need to be explicitly declared at compile time to limiting the values of an expression at run time in C++. In C++ 11, Type Inference concept is introduced, and the compiler will deduct the type during the compilation itself on its own. The time for the compilation process increases slightly, but it does not affect run time of program.



Before C++11, the auto keyword was used for storage duration specification. In the new standard its purpose was completely changed. 'auto' keyword is telling the compiler it has to deduce the actual type of a variable that is being declared from its initializer. It can be used when declaring variables in different scopes such as namespaces, blocks or initialization statement of for loops.

auto x = 4;  // x is an int
auto y = 3.37;  // y is an double
auto ptr = &x;  // ptr is pointer to integer
auto f = new foo(); // f is a foo*

Using auto usually means less code (its pritty silly, but it will be sense for some cases). A good use of auto is to avoid long initializations when creating iterators for containers.

std::map<std::string, std::vector<int>> map;
for(auto it = begin(map); it != end(map); ++it) 
{
}

decltype keyword:

The decltype is a keyword introduced in C++11, used to query the type of an expression at compile-type.

It inspects the declared type of an entity or the type of an expression. 'auto' lets you declare a variable with particular type whereas 'decltype' lets you extract the type from the variable, so decltype is sort of an operator that evaluates the type of passed expression.

#include <iostream>
using namespace std;
 
struct A { double x; };
const A* a = new A{0};

int n   = 20;

const int& foo() {
     return n;
}

const int zoo() {
 return n;
}

int main() {

 decltype(n) i;        // type is int
 cout <<  typeid(i).name() << endl;
 
 decltype(foo()) j = foo(); // type is const int&
    cout <<  typeid(j).name() << ":" << j << endl;
 
 decltype(zoo()) x;    // type is int
 cout <<  typeid(x).name() << endl; 

 decltype(a->x) y;        // type of y is double (declared type)
 cout <<  typeid(y).name() << endl;
 y = 55.6;
 
 decltype((a->x)) z = y;  // type of z is const double& (lvalue expression)
    cout <<  typeid(z).name() << ":" << z << endl;
}