Namespaces
Variants
Views
Actions

decltype specifier

From cppreference.com
< cpp‎ | language

Inspects the declared type of an entity or queries the type and value category of an expression.

Contents

[edit] Syntax

decltype ( entity ) (1) (since C++11)
decltype ( expression ) (2) (since C++11)

[edit] Explanation

1) If the argument is an expression that is either the unparenthesised name of an object or a function, or a member access expression (object.member or pointer->member), then decltype yields the type of the entity specified by this expression.
2) If the argument is any other expression of type T, then:
a) if the value category of expression is xvalue, decltype yields T&&;
b) if the value category of expression is lvalue, decltype yields T&;
c) if the value category of expression is prvalue, decltype yields T.

If expression is a function call which returns a prvalue of class type or is a comma expression whose right operand is such a function call, a temporary object is not introduced for that prvalue. The class type need not be complete or have an available destructor. This rule doesn't apply to sub-expressions:in decltype(f(g())), g() must have a complete type, but f() need not.

Note that if the name of an object is parenthesised, it is treated as an ordinary lvalue expression, thus decltype(x) and decltype((x)) are often different types.

decltype is useful when declaring types that are difficult or impossible to declare using standard notation, like lambda-related types or types that depend on template parameters.

[edit] Keywords

decltype

[edit] Example

#include <iostream>
 
struct A { double x; };
const A* a = new A {0};
 
decltype(a->x) x3;        // type of x3 is double (declared type)
decltype((a->x)) x4 = x3; // type of x4 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
 
int main() 
{
    int i = 33;
    decltype(i) j = i * 2;
 
    std::cout << "i = " << i << ", "
              << "j = " << j << '\n';
 
    auto f = [](int a, int b)->int
    {
        return a * b;
    };
 
    decltype(f) f2 = f; // the type of a lambda function is unique and unnamed
    i = f(2, 2);
    j = f2(3, 3);
 
    std::cout << "i = " << i << ", "
              << "j = " << j << '\n';
}

Output:

i = 33, j = 66
i = 4, j = 9

[edit] See also

(C++11)
obtains the type of expression in unevaluated context
(function template) [edit]