I haven't been able to find a good explanation of decltype. Please tell me, as a beginning programmer, what it does and why it is useful.
For example, I am reading a book that asked the following question. Can someone explain to me the answer and why, along with some good (beginner-level) examples?
What would be the type of each variable and what value would each variable have when the code finishes?
int a = 3, b = 4; decltype(a) c = a; decltype((b)) d = a; ++c; ++d;
A line-by-line explanation would be very helpful.
Decltype keyword in C++ Decltype stands for declared type of an entity or the type of an expression. It lets you extract the type from the variable so decltype is sort of an operator that evaluates the type of passed expression. SYNTAX : decltype( expression )
The decltype type specifier yields the type of a specified expression. The decltype type specifier, together with the auto keyword, is useful primarily to developers who write template libraries. Use auto and decltype to declare a template function whose return type depends on the types of its template arguments.
auto is a keyword in C++11 and later that is used for automatic type deduction. The decltype type specifier yields the type of a specified expression. Unlike auto that deduces types based on values being assigned to the variable, decltype deduces the type from an expression passed to it.
decltype returnsIf what we pass to decltype is the name of a variable (e.g. decltype(x) above) or function or denotes a member of an object ( decltype x.i ), then the result is the type of whatever this refers to. As the example of decltype(y) above shows, this includes reference, const and volatile specifiers.
decltype
is a way to specify a type: You give it an expression, and decltype
gives you back a type which corresponds to the type of the expression. Specifically, decltype(e)
is the following type:
If e
is the name of a variable, i.e. an "id-expression", then the resulting type is the type of the variable.
Otherwise, if e
evaluates to an lvalue of type T
, then the resulting type is T &
, and if e
evaluates to an rvalue of type T
, then the resulting type is T
.
Combining these rules with reference collapsing rules allows you to make sense of decltype(e) &&
, which is always a "suitable" reference. (C++14 also adds decltype(auto)
to give you the type-deduction of auto
combined with the value category semantics of decltype
.)
Examples:
int foo(); int n = 10; decltype(n) a = 20; // a is an "int" [id-expression] decltype((n)) b = a; // b is an "int &" [(n) is an lvalue] decltype(foo()) c = foo(); // c is an "int" [rvalue] decltype(foo()) && r1 = foo(); // int && decltype((n)) && r2 = n; // int & [& && collapses to &]
It might be worth stressing the difference between auto
and decltype
: auto
works on types, and decltype
works on expressions.
You shouldn't be seeing or using decltype
in "day-to-day" programming. It is most useful in generic (templated) library code, where the expression in question is not known and depends on a paramater. (By contrast, auto
may be used generously all over the place.) In short, if you're new to programming, you probably won't need to use decltype
for some time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With