decltype
specifier(since C++11)General topics | ||||||||||||||||
Flow control | ||||||||||||||||
Conditional execution statements | ||||||||||||||||
Iteration statements (loops) | ||||||||||||||||
Jump statements | ||||||||||||||||
Functions | ||||||||||||||||
Function declaration | ||||||||||||||||
Lambda function expression | ||||||||||||||||
inline specifier | ||||||||||||||||
Dynamic exception specifications(until C++17*) | ||||||||||||||||
noexcept specifier(C++11) | ||||||||||||||||
Exceptions | ||||||||||||||||
Namespaces | ||||||||||||||||
Types | ||||||||||||||||
Specifiers | ||||||||||||||||
| ||||||||||||||||
Storage duration specifiers | ||||||||||||||||
Initialization | ||||||||||||||||
Expressions | ||||||||||||||||
Alternative representations | ||||||||||||||||
Literals | ||||||||||||||||
Boolean -Integer -Floating-point | ||||||||||||||||
Character -String -nullptr(C++11) | ||||||||||||||||
User-defined(C++11) | ||||||||||||||||
Utilities | ||||||||||||||||
Attributes(C++11) | ||||||||||||||||
Types | ||||||||||||||||
typedef declaration | ||||||||||||||||
Type alias declaration(C++11) | ||||||||||||||||
Casts | ||||||||||||||||
Memory allocation | ||||||||||||||||
Classes | ||||||||||||||||
Class-specific function properties | ||||||||||||||||
| ||||||||||||||||
Special member functions | ||||||||||||||||
Templates | ||||||||||||||||
Miscellaneous | ||||||||||||||||
|
Inspects the declared type of an entity or the type and value category of an expression.
Contents |
decltype ( entity) | (1) | ||||||||
decltype ( expression) | (2) | ||||||||
If the argument is an unparenthesizedid-expression naming astructured binding, then decltype yields thereferenced type (described in the specification of the structured binding declaration). | (since C++17) |
If the argument is an unparenthesizedid-expression naming aconstant template parameter, then decltype yields the type of the template parameter (after performing any necessary type deduction if the template parameter is declared with a placeholder type). The type is non-const even if the entity is a template parameter object (which is a const object). | (since C++20) |
T
, andIfexpression is a function call which returns a prvalue of class type or is acomma expression whose right operand is such a function call, a temporary object is not introduced for that prvalue. | (until C++17) |
Ifexpression is a prvalue other than a (possibly parenthesized)immediate invocation(since C++20), a temporary object is notmaterialized from that prvalue: such prvalue has no result object. | (since C++17) |
Note that if the name of an object is parenthesized, it is treated as an ordinary lvalue expression, thusdecltype(x) anddecltype((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.
Feature-test macro | Value | Std | Feature |
---|---|---|---|
__cpp_decltype | 200707L | (C++11) | decltype |
#include <cassert>#include <iostream>#include <type_traits> 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;} constint& getRef(constint* p){return*p;}static_assert(std::is_same_v<decltype(getRef),constint&(constint*)>);auto getRefFwdBad(constint* p){return getRef(p);}static_assert(std::is_same_v<decltype(getRefFwdBad),int(constint*)>,"Just returning auto isn't perfect forwarding.");decltype(auto) getRefFwdGood(constint* p){return getRef(p);}static_assert(std::is_same_v<decltype(getRefFwdGood),constint&(constint*)>,"Returning decltype(auto) perfectly forwards the return type."); // Alternatively:auto getRefFwdGood1(constint* p)-> decltype(getRef(p)){return getRef(p);}static_assert(std::is_same_v<decltype(getRefFwdGood1),constint&(constint*)>,"Returning decltype(return expression) also perfectly forwards the return type."); int main(){int i=33; decltype(i) j= i*2; static_assert(std::is_same_v<decltype(i), decltype(j)>);assert(i==33&&66== j); auto f=[i](int av,int bv)->int{return av* bv+ i;};auto h=[i](int av,int bv)->int{return av* bv+ i;}; static_assert(!std::is_same_v<decltype(f), decltype(h)>,"The type of a lambda function is unique and unnamed"); decltype(f) g= f;std::cout<< f(3,3)<<' '<< g(3,3)<<'\n';}
Output:
42 42
Extended content |
---|
|
This section is incomplete Reason: Requires correction. See:Talk: Wrong References. |
auto specifier(C++11) | specifies a type deduced from an expression[edit] |
(C++11) | obtains a reference to an object of the template type argument for use in an unevaluated context (function template)[edit] |
(C++11) | checks if two types are the same (class template)[edit] |
C documentation fortypeof |