Ch2.11: decltype(T)
What is decltype?
The keyword decltype inspects the type of an expression and produces that type.
Unlike auto, which deduces from an initializer, decltype gives you the exact type of an expression without creating an object.
Basic Examples
#include <cstddef>
::std::size_t x{42zu};
decltype(x) a{100zu}; // a has type ::std::size_t
decltype(42zu) b{200zu}; // b has type ::std::size_t
decltype(x + 1) c{300zu}; // c has type ::std::size_t
decltype takes the type of the expression inside the parentheses and uses it for the declaration.
Difference from auto
autodeduces type from an initializer.decltypeinspects the type of an expression, even without initializing.automay adjust types (e.g., strip references), whiledecltypepreserves them exactly.
References with decltype
#include <cstddef>
::std::size_t y{500zu};
::std::size_t& ry{y};
decltype(ry) d{y}; // d has type ::std::size_t& (reference)
decltype preserves reference types. If the expression is a reference, the declared object will also be a reference.
Const with decltype
#include <cstddef>
::std::size_t const z{600zu};
decltype(z) e{700zu}; // e has type ::std::size_t const
decltype also preserves const qualifiers from the inspected expression.
⚠️ Beware: decltype(x) vs decltype((x))
#include <cstddef>
::std::size_t v{800zu};
decltype(v) a{900zu}; // a has type ::std::size_t
decltype((v)) b{v}; // b has type ::std::size_t& (reference)
The difference comes from how decltype rules treat expressions:
decltype(x)— when the name of an object appears without parentheses, the type is the declared type of the object (here::std::size_t).decltype((x))— when the expression is wrapped in parentheses, it is treated as an lvalue expression. The type becomesT&(here::std::size_t&).
In short: decltype(x) gives the declared type, while decltype((x)) gives a reference type because the expression (x) is an lvalue.
Key Takeaways
decltypeproduces the type of an expression.- Unlike
auto, it does not require an initializer. decltypepreserves references andconstqualifiers.decltype(x)is the declared type ofx.decltype((x))is a reference type, because(x)is an lvalue expression.