Decltype type Specifier in C++
The primary use of C++ decltype is to inspect the declaration type of an entity in an expression. The auto keyword can declare a particular type of variable, whereas the decltype keyword can extract the variable type from another variable. The auto keyword can use all the entities to declare the variable, whereas the decltype keyword is used to extract the variable from the entity.
What is C++ decltype?
The decltype is a type of operator in C++ that is used to inspect the data type of a particular expression. This feature is available in the C++ 11th version. It is also called C++0x. This specifier performs the expression as an operand. We can also say that the variable defined by using the particular data type can be replaced by the compiler. The information about the data type is provided during the compilation time. Also, info about the decltype can also be provided during the compilation time. The information about the running status of the variable can be supplied by the Typeid type.
Example-1
#include <iostream>
int main() {
int j = 55, * k = & j;
decltype (* k) c = j;
std::cout<<*k;
return 0;
}
Output:
55
Syntax for C++ decltype
We can declare the decltype in C++ as follows.
decltype( expression )
Here, expression is the only parameter of the decltype in C++. Expressions are the sequence of operands and the operator used for computing purpose.
Guidelines for decltype in C++
There is some guidelines for the use of the decltype operator in C++. The guidelines are as follows:
- Suppose the expression parameter has permission to access the member of the class. This class belongs to the type of class entity.
Example 2:
#include <iostream>
#include <type_traits>
struct A { double x; };
const A* a;
decltype(a->x) y;
decltype((a->x)) z = y;
template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u{
return t + u;
}
const int& getRef(const int* p) { return *p; }
static_assert(std::is_same_v<decltype(getRef), const int&(const int*)>);
auto getRefFwdBad(const int* p) { return getRef(p); }
static_assert(std::is_same_v<decltype(getRefFwdBad), int(const int*)>,
"Just returning auto isn't perfect forwarding.");
decltype(auto) getRefFwdGood(const int* p) { return getRef(p); }
static_assert(std::is_same_v<decltype(getRefFwdGood), const int&(const int*)>,
"Returning decltype(auto) perfectly forwards the return type.");
auto getRefFwdGood1(const int* p) -> decltype(getRef(p)) { return getRef(p); }
static_assert(std::is_same_v<decltype(getRefFwdGood1), const int&(const int*)>,
"Returning decltype(return expression) also perfectly forwards the return type.");
int main()
{
int i = 33;
decltype(i) j = i * 2;
std::cout << "i and j are the same type? " << std::boolalpha
<< std::is_same_v<decltype(i), decltype(j)> << '\n';
std::cout << "i = " << i << ", "
<< "j = " << j << '\n';
auto f = [](int a, int b) -> int
{
return a * b;
};
decltype(f) g = f;
i = f(2, 2);
j = g(3, 3);
std::cout << "i = " << i << ", "
<< "j = " << j << '\n';
}
Output:
i and j are the same type? true
i = 33, j = 66
i = 4, j = 9
Example 3:
#include <bits/stdc++.h>
using namespace std;
int function1() { return 29; }
char function2() { return 'h'; }
int main()
{
decltype(function1()) a;
decltype(function2()) b;
cout << typeid(a).name() << endl;
cout << typeid(b).name() << endl;
return 0;
}
Output:
i
c
Explanation
In the above example, first, we have created two variables of different data types. The first variable is function1, and it is of int type. The second variable is function2 which is of the char type. Then, in the main program, we have used the decltype specifier and assigned the two variables function1 and function2. Then, we have used two cout functions along with the typeid and passed the values a and b to it that returns the result after comparing the data type of a and b and the return type of function1 and function2.
Example 3:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int p = 10;
decltype(p) h = p + 10;
cout << typeid(h).name();
return 0;
}
Output:
i
Explanation
In the above example, we have initialized a variable a of the int type and assigned the value 7. Then, we have used the decltype specifier and passed the variable a to it. Then, we have assigned the a+7 value to g. After that, we have used the cout to print the output.