Bracket syntax for determining ltyval type

I am trying to better understand decltype in order to determine the type of expression at compile time. Say, for example, I am doing this with a double variable:

#include <iostream>
#include <type_traits>

int main(){
    double a;
    typedef decltype(a) a_type;
    typedef decltype((a)) ref_a_type;
    typedef decltype(a)& o_ref_a_type;

    a_type b;
    ref_a_type c = b;
    o_ref_a_type d = b;

  if (std::is_same<decltype(b), double>::value) std::cout << "b is double\n";
  if (std::is_same<decltype(c), double&>::value) std::cout << "c is double&\n";
  if (std::is_same<decltype(d), double&>::value) std::cout << "d is double&\n";
}

If I understood correctly, these points should be true:

  • decltype(a)returns double&if ais an lvalue value and doubleotherwise.
  • decltype infers the type of an expression if it does not apply to the variable, in which case it infers the type of the variable.
  • If the variable is enclosed in brackets, it becomes an lvalue expression.

Thus, decltype((a))they are decltype(a)&equivalent in this case, but not always equivalent, for example, if ait is not a variable:

typedef decltype((5)) ref_a_type;
typedef decltype(5)& o_ref_a_type;

(ref_a_type is int o_ref_a_type is int&, ). - ? ? , .

+4
1

decltype(e) - , ++, , ( [dcl.type.simple]):

e , decltype(e), : (4.1) - e - id- (5.2.5), decltype(e) e. e , ,
(4.2) - , e - x, decltype(e) - T&&, T - e,
(4.3) - , e lvalue, decltype(e) T&, T - e; (4.4) - decltype(e) e.

, :

  • decltype(a): a - unparenthesized id-expression, a: double.
  • decltype((a)): , . a x, lvalue, double&.
  • decltype(a)&: , double&.
  • decltype((5)): id- ( ), xvalue lvalue - , : int.
  • decltype(5)&: , , , &, int&.

?

, . - , , .

decltype(expr)& lvalue - .

decltype((expr)) ( decltype((5))), lvalue ( decltype((a))) rvalue ( decltype((std::move(a)))).

+2