Объявление переменной `auto` с фундаментальными типами из нескольких слов вызывает ошибку - PullRequest
2 голосов
/ 12 октября 2019

Можно ли объявить переменную с ключевым словом auto и именем типа, состоящим из двух или более слов?

А если нет, то почему бы и нет?

Например

auto foo = unsigned int{0};

Дайте следующий вывод компилятора

Clang:

error: expected '(' for function-style cast or type construction

GCC:

error: expected primary-expression before 'unsigned'

Ответы [ 3 ]

3 голосов
/ 12 октября 2019

Чтобы

auto foo = T{0};

работал, T должен быть спецификатором простого типа .

Из C ++ 11Стандарт / 5.2.3 Явное преобразование типов (функциональная запись) / 3

Аналогично, спецификатор простого типа или typename-спецификатор , за которым следует braced-init-list создает временный объект указанного типа direct-list-initialized ( [dcl.init.list]) с указанным braced-init-list , и его значением является этот временный объект в качестве значения.

Если вы видите определениеиз спецификатор простого типа , unsigned int не является одним из них.

Вы можете использовать любое из следующего:

auto foo = 0U;
auto foo = (unsigned int)0;
auto foo = static_cast<unsigned int>(0);
2 голосов
/ 12 октября 2019

Всякий раз, когда вы хотите, чтобы компилятор группировал несколько вещей, но это не так, вы используете скобки, чтобы принудительно это сделать:

auto foo = (unsigned int)(0);

Обратите внимание, что как @ cpplearnern указывает, если вывместо этого используйте фигурные скобки, он считается составным литералом и не является допустимым C ++, хотя допустим C99:

auto foo = (unsigned int){0}; /* Not legal C++, though GCC and Clang support it. */

В любом случае, лучшим решением является использование целочисленные литералы :

auto foo = 0u;
1 голос
/ 12 октября 2019

То, что вы ищете, это, вероятно, здесь http://www.cplusplus.com/doc/tutorial/typecasting/ (раздел "Приведение типов").

И, возможно, это даже лучше: https://en.cppreference.com/w/cpp/language/explicit_cast По этой ссылке выиспользуя синтаксис (5): new_type { expression-list(optional) }.

Итак, если у вас есть пробел в имени типа, как компилятор догадается, если unsigned int {0} равно (unsigned int) {0} (что вы имели в виду, вероятно), или это (unsigend (int {0})) (что на самом деле будет двумя преобразованиями) ... так что вы должны явно указать имя типа в скобках.

Это было бы важно, если бы вы захотели сделать long unsigned {x}, потому что тогда я бы получил

  • long, если он будет интерпретирован как long (unsigned {x})
  • unsigned long, если оно интерпретируется как (long unsigned){x}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...