Учитывать:
(long long){1};
Это не выражение приведения в стиле C для [expr.cast]/1:
Результат выражения (T) cast-expression имеет тип T. Результатом является значение lvalue, если T является ссылочным типом lvalue, или ссылка rvalue на тип функции, и значение x, если T является ссылкой rvalue на тип объекта; в противном случае результатом будет prvalue.
литой-выражение:
- унарное выражение
- ( type-id ) приведение-выражение
{1}
не должно быть литым выражением.
Это также не выражение приведения в функциональном стиле для [expr.type.conv]/1:
Спецификатор простого типа или спецификатор имени типа, за которым следует необязательный список-выражений в скобках или список-инициализации в фигурных скобках (инициализатор), создает значение указанного типа с учетом инициализатора. Если тип является заполнителем для выведенного типа класса, он заменяется возвращаемым типом функции, выбранной разрешением перегрузки для вывода шаблона класса для оставшейся части этого подпункта. В противном случае, если тип содержит тип-заполнитель, он заменяется типом, определяемым выводом типа-заполнителя ([dcl.type.auto.deduct]).
спецификатор простого типа:
- вложенный спецификатор имени opt имя типа
- шаблон спецификатора вложенного имени, простой идентификатор шаблона
- спецификатор decltype
- описатель типа заполнителя
- вложенный спецификатор имени opt имя-шаблона
- уголь
- char8_t
- char16_t
- char32_t
- wchar_t
- логический
- короткий
- инт
- длинный
- подписал
- неподписанный
- плавать
- двойной
- пустота
(long long)
не должен быть спецификатором простого типа.
Это не кажется законным, но должно быть, почему?
Это недопустимый синтаксис в стандарте ISO C++.
В C это синтаксис составного литерала. Компиляторы по умолчанию часто поддерживают это также в режиме C++ в качестве расширения. При включении строгого (более) стандартного соответствия они должны отклонить его или, по крайней мере, предоставить предупреждение (например, с помощью -pedantic
, -pedantic-errors
)
Между прочим, не имеет значения, есть ли несколько слов. (long){1}
такая же проблема. (/*..*/){/*..*/}
не может быть синтаксисом для выражения, как видно из приведенных вами стандартных кавычек.
Кроме того, в C такой составной литерал является lvalue, как и строковые литералы. Это могло бы сбивать с толку в C++, где аналогичное выражение приведения, то есть T{1}
с using T=long long;
, дает значение prvalue. Время жизни полученного объекта также сильно отличается. Следовательно, их поддержка в C++ либо имела бы другое значение, чем в C, либо означала бы сбивающую с толку разницу между (T){e}
и T{e}
.
Вот закрытое предложение от 2020-2022 по внедрению составных литералов в C++. Как видно из результатов голосования, единого мнения о том, добавлять ли их вообще и какое поведение они должны иметь, не было.