А зачем если можно в плюсах сделать auto?
If the argument is an unparenthesized id-expression or an unparenthesized class member access expression, then decltype yields the type of the entity named by this expression. If there is no such entity, or if the argument names a set of overloaded functions, the program is ill-formed.
If the argument is an unparenthesized id-expression naming a non-type 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).
(since C++20)
2) If the argument is any other expression of type T, and
a) if the value category of expression is xvalue, then decltype yields T&&;
b) if the value category of expression is lvalue, then decltype yields T&;
c) if the value category of expression is prvalue, then decltype yields T.
If expression is a prvalue other than a (possibly parenthesized) immediate invocation (since C++20), a temporary object is not materialized from that prvalue: such prvalue has no result object.
(since C++17)
The type need not be complete or have an available destructor, and can be abstract. 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 parenthesized, it is treated as an ordinary lvalue expression, thus decltype(x) and decltype((x)) are often different types.
изич, понял теперь, зачем decltype?