Подтвердить что ты не робот

Значение круглых скобок в 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?

4b9b3361

Ответ 1

  • c - это имя переменной;

  • (c) - выражение, в данном случае выражение lvalue, значение которого идентично значению переменной c.

И они обрабатываются по-разному на 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]