Type Inference in C++ (auto and decltype)
Last Updated :
07 Mar, 2025
Type Inference refers to automatic deduction of the data type of an expression in a programming language. Before C++ 11, each data type needed to be explicitly declared at compile-time, limiting the values of an expression at runtime but after the new version of C++, keywords such as auto and decltype are included which allows a programmer to leave the type deduction to the compiler itself.
With type inference capabilities, we can spend less time having to write out things the compiler already knows. As all the types are deduced in the compiler phase only, the time for compilation increases slightly but it does not affect the run time of the program.
Type inference can simplify your code and improve readability.
1. auto in C++
The auto keyword in C++ specifies that the type of the variable that is being declared will be automatically deducted from its initializer. In the case of functions, if their return type is auto, then that will be evaluated by return type expression at compile time. Good use of auto is to avoid long initializations when creating iterators for containers.
Note: The variable declared with auto keyword should be initialized at the time of its declaration only or else there will be a compile-time error.
Example of auto in C++
CPP
// C++ program to demonstrate working of auto
// and type inference
#include <bits/stdc++.h>
using namespace std;
int main()
{
// auto a; this line will give error
// because 'a' is not initialized at
// the time of declaration
// a=33;
// see here x ,y,ptr are
// initialised at the time of
// declaration hence there is
// no error in them
auto x = 4;
auto y = 3.37;
auto z = 3.37f;
auto c = 'a';
auto ptr = &x;
auto pptr = &ptr; //pointer to a pointer
cout << typeid(x).name() << endl
<< typeid(y).name() << endl
<< typeid(z).name() << endl
<< typeid(c).name() << endl
<< typeid(ptr).name() << endl
<< typeid(pptr).name() << endl;
return 0;
}
Note: We have used typeid for getting the type of the variables.
Here, typeid is an operator that is used where the dynamic type of an object needs to be known.
typeid(x).name() returns the data type of x, for example, it returns:
- ‘i’ for integers, ‘d’ for doubles,
- ‘f’ for float, ‘c’ for char,
- Pi’ for the pointer to the integer,
- ‘Pd’ for the pointer to double,’
- Pf’ for the pointer to float,
- ‘Pc’ for the pointer to char,
- ‘PPi’ for the pointer to pointer to integer.
- Single Pointer results in prefix ‘P’,
- double-pointer results in ‘PP’ as a prefix and so on.
But the actual name returned is mostly compiler-dependent.
Note: Good use of auto is to avoid long initializations when creating iterators for containers.
Example of C++ auto Keyword
C++
// C++ program to demonstrate that we can use auto to
// save time when creating iterators
#include <bits/stdc++.h>
using namespace std;
int main()
{
// Create a set of strings
set<string> st;
st.insert({ "geeks", "for", "geeks", "org" });
// 'it' evaluates to iterator to set of string
// type automatically
for (auto it = st.begin(); it != st.end(); it++)
cout << *it << " ";
return 0;
}
Note: auto becomes int type if even an integer reference is assigned to it. To make it reference type, we use auto &.
- Function that returns a ‘reference to int’ type : int& fun() {};
- m will default to int type instead of int& type : auto m = fun();
- n will be of int& type because of use of extra & with auto keyword : auto& n = fun();
2. decltype in C++
The decltype keyword in C++ inspects the declared type of an entity or the type of an expression. ‘auto’ lets you declare a variable with a 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.
Explanation of the above keywords and their uses is given below:
Example of decltype in C++
CPP
// C++ program to demonstrate use of decltype
#include <bits/stdc++.h>
using namespace std;
int fun1() { return 10; }
char fun2() { return 'g'; }
int main()
{
// Data type of x is same as return type of fun1()
// and type of y is same as return type of fun2()
decltype(fun1()) x;
decltype(fun2()) y;
cout << typeid(x).name() << endl;
cout << typeid(y).name() << endl;
return 0;
}
Below is one more example to demonstrate the use of decltype,
Example of C++ decltype Keyword
CPP
// C++ program to demonstrate use of decltype
#include <bits/stdc++.h>
using namespace std;
// Driver Code
int main()
{
int x = 5;
// j will be of type int : data type of x
decltype(x) j = x + 5;
cout << typeid(j).name();
return 0;
}
Example: C++ Program that Demonstrates the Use of Both auto and decltype
Below is a C++ template function min_type() that returns the minimum of two numbers. The two numbers can be of any integral type. The return type is determined using the type of minimum of two.
CPP
// C++ program to demonstrate use of decltype in functions
#include <bits/stdc++.h>
using namespace std;
// A generic function which finds minimum of two values
// return type is type of variable which is minimum
template <class A, class B>
auto findMin(A a, B b) -> decltype(a < b ? a : b)
{
return (a < b) ? a : b;
}
// driver function to test various inference
int main()
{
// This call returns 3.44 of double type
cout << findMin(4, 3.44) << endl;
// This call returns 3 of double type
cout << findMin(5.4, 3) << endl;
return 0;
}
decltype vs typeid
Following are some main difference between decltype and typeid
- Decltype gives the type information at compile time while typeid gives at runtime.
- So, if we have a base class reference (or pointer) referring to (or pointing to) a derived class object, the decltype would give type as base class reference (or pointer, but typeid would give the derived type reference (or pointer).
Similar Reads
C++ STL Algorithm Library
Standard Template Library (STL) offers a rich collection of algorithms designed to operate on STL containers and beyond. It provides commonly used algorithms such as sorting, searching, copying, etc. These well tested algorithms are optimized for performance and provide a way to write cleaner, faste
4 min read
sort() in C++ STL
In C++, sort() is a built-in function used to sort the given range in desired order. It provides a simple and efficient way to sort the data in C++ but it only works on data structures that provide random access to its elements such as vectors and arrays. Let's take a look at an example: [GFGTABS] C
4 min read
Type Inference in C++ (auto and decltype)
Type Inference refers to automatic deduction of the data type of an expression in a programming language. Before C++ 11, each data type needed to be explicitly declared at compile-time, limiting the values of an expression at runtime but after the new version of C++, keywords such as auto and declty
6 min read
transform() in C++ STL
In C++, transform() is a built-in STL function used to apply the given operation to a range of elements and store the result in another range. Letâs take a look at a simple example that shows the how to use this function: [GFGTABS] C++ #include <bits/stdc++.h> using namespace std; int main() {
4 min read
Variadic function templates in C++
Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration. However, variadic templates help to overcome this issue. Douglas Gregor
3 min read
Template Specialization in C++
Template in C++is a feature. We write code once and use it for any data type including user defined data types. For example, sort() can be written and used to sort any data type items. A class stack can be created that can be used as a stack of any data type. What if we want a different code for a p
5 min read
Merge operations using STL in C++ | merge(), includes(), set_union(), set_intersection(), set_difference(), ., inplace_merge,
Some of the merge operation classes are provided in C++ STL under the header file "algorithm", which facilitates several merge operations in a easy manner. Some of them are mentioned below. merge(beg1, end1, beg2, end2, beg3) :- This function merges two sorted containers and stores in new container
7 min read
std::partition in C++ STL
C++ has a class in its STL algorithms library which allows us easy partition algorithms using certain inbuilt functions. Partition refers to act of dividing elements of containers depending upon a given condition. Partition operations :1. partition(beg, end, condition) :- This function is used to pa
5 min read
accumulate() and partial_sum() in C++ STL
accumulate() and partial_sum() functions are used to find the sum or any other accumulated value that is obtained by doing the addition or any other binary operation on the elements in the given range. Both of these functions are the part of STL Numeric Library and defined inside <numeric> hea
4 min read
numeric header in C++ STL | Set 2 (adjacent_difference(), inner_product() and iota())
The numeric header is part of the numeric library in C++ STL. This library consists of basic mathematical functions and types, as well as optimized numeric arrays and support for random number generation. Some of the functions in the numeric header: iotaaccumulatereduceinner_productpartial_sum etc.
4 min read