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

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:

In short: decltype(x) gives the declared type, while decltype((x)) gives a reference type because the expression (x) is an lvalue.

Key Takeaways