1. Grammar
decltype ( expression )
decltype (declare type) is used to query the type of expression, that is, automatic type inference at compile time. As shown above, this statement returns the type of expression.
Note: decltype is only the type of the query expression, it does not evaluate the expression.
2. Derivation Rules
1) If expression is an expression not ( )
surrounded by parentheses , or a class member access expression, or a single variable, then the type of decltype(exp) is consistent with exp, which is the most common and common situation .
2) If the expression is a function call, then the type of decltype(exp) is consistent with the type of the return value of the function.
3) If expression is an lvalue or ( )
surrounded by parentheses , then the type of decltype(expression) is the reference of expression; assuming that the type of expression is T, then the type of decltype(expression) is T&.
3. auto given decltype
auto varname = value;
decltype(exp) varname = value;
1) auto =
deduces the type of the variable based on the initial value value on the right, while decltype deduces the type of the variable based on the exp expression, which =
has nothing to do with the value on the right;
2) Auto requires variables to be initialized, but decltype does not require it, that is, it can be written as "decltype(exp) varname;";
4. Basic use
const int&& foo();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1 = 1; // const int&& (1)
decltype(i) x2; // int (2)
decltype(a->x) x3; // double (3)
decltype((a->x)) x4 = 1; // double& (4)
5. Examples
#include <iostream>
#include <type_traits>
using namespace std;
struct A { double x; };
const A* a;
decltype(a->x) y; // type of y is double (declared type)
decltype((a->x)) z = y; // type of z is const double& (lvalue expression)
template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) // return type depends on template parameters
// return type can be deduced since C++14
{
return t + u;
}
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; // the type of a lambda function is unique and unnamed
i = f(2, 2);
j = g(3, 3);
std::cout << "i = " << i << ", "
<< "j = " << j << '\n';
system("pause");
return 0;
}