decltype и круглые скобки - PullRequest
48 голосов
/ 23 июня 2010

Я не понимаю последнюю строку примера на странице 148 FCD (§7.6.1.2 / 4):

const int&& foo();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1 = i;     // type is const int&&
decltype(i) x2;             // type is int
decltype(a->x) x3;          // type is double
decltype((a->x)) x4 = x3;   // type is const double&

Почему скобки имеют значение здесь? Разве это не должно быть просто double как в строке выше?

Ответы [ 3 ]

39 голосов
/ 23 июня 2010

Чуть выше этого примера написано

  • , если e - это не выраженное в скобках id-выражение или доступ к члену класса (5.2.5), decltype (e) - это типсущность, названная e.
  • , если e - lvalue, decltype (e) - T &, где T - тип e;

Я думаю, decltype(a->x)пример "доступа к члену класса" и decltype((a->x)) является примером lvalue.

17 голосов
/ 23 июня 2010
decltype(a->x)

Это дает вам тип переменной члена A::x, которая равна double.

decltype((a->x))

Это дает вам тип выражения (a->x), которое является выражением lvalue (следовательно, почему это константная ссылка - a является const A*).

9 голосов
/ 23 июня 2010

Добавленные парены превращают его в lvalue.

MSDN говорит
Внутренние скобки приводят к тому, что оператор оценивается как выражение, а не как членский доступ. А поскольку a объявлен как указатель const, тип является ссылкой на const double.

...