Значение круглых скобок в decltype ((c))?
Я читал эту статью в Википедии о функции C++11
Type Inference.
Есть пример, и я цитирую:
#include <vector>
int main() {
const std::vector<int> v(1);
auto a = v[0]; // a has type int
decltype(v[1]) b = 1; // b has type const int&, the return type of
// std::vector<int>::operator[](size_type) const
auto c = 0; // c has type int
auto d = c; // d has type int
decltype(c) e; // e has type int, the type of the entity named by c
decltype((c)) f = c; // f has type int&, because (c) is an lvalue
decltype(0) g; // g has type int, because 0 is an rvalue
}
в следующих строках:
decltype(c) e; // e has type int, the type of the entity named by c
decltype((c)) f = c; // f has type int&, because (c) is an lvalue
В чем разница между c
и (c)
? Почему (c)
представляет lvalue?
Ответы
Ответ 1
И они обрабатываются по-разному на decltype
. Рассмотрим, например, decltype(1+2)
, что также является примером выражения. Просто случается так, что ваш пример - простая версия выражения: одна, которая просто называет одну переменную и не делает ничего интересного с ней.
Это одно из тех различий, которые вам в основном нравятся только в том случае, если вы рационализируете тонкие части спецификации языка; хотя, как вы определили, в этом случае он имеет весьма существенный практический эффект.
Обратите внимание, что здесь не используется оператор. Все это просто вывод из макета грамматики.
Ответ 2
Я нашел хорошее описание здесь. Он описывает разницу между:
struct A { double x; };
const A* a = new A();
...
decltype(a->x) x4; // type is double
decltype((a->x)) x5; // type is const double&
и я цитирую:
Причина разницы между двумя последними вызовами типа decltype заключается в том, что выражение в скобках (a->x)
не является идентификатором id или выражением доступа к члену и поэтому не обозначает именованный объект. [13]
Поскольку выражение является значением lvalue, его выводимый тип является "ссылкой на тип выражения" или const double&
. [10]