Ответ 1
IMO, формулировка в [stmt.ambig] достаточно ясна для этого:
Оператор выражения с преобразованием явного типа в стиле функции как его самое левое подвыражение может быть неотличимым от объявления, где первый декларатор начинается с
(
. В этих случаях оператор является объявлением.[Примечание: Если оператор не может синтаксически быть объявлением, нет никакой двусмысленности, поэтому это правило не применяется. Весь анализ, возможно, потребуется изучить, чтобы определить, так ли это.
В формулировке говорится о целом (выражение).
Ваш оператор не может быть проанализирован как объявление, потому что lexeme 1
не является грамматически не декларатором. Нет никакой двусмысленности: он выглядел бы двусмысленным, если бы мы смотрели исключительно на int(x)
, но стандарт явно явно отрицает, что если какой-либо префикс оператора анализирует как объявление, весь оператор считается потенциальным объявлением.
Фактически, основные эксперты имели очень похожие обсуждения в 2002 году над основной проблемой 340 --- Я выделил важные биты. Здесь, опять же, мы имеем предполагаемое объявление, которое содержит несовместимую подконструкцию.
Рассмотрим следующую программу:
struct Point { Point(int){} }; struct Lattice { Lattice(Point, Point, int){} }; int main(void) { int a, b; Lattice latt(Point(a), Point(b), 3); /* Line X */ }
Проблема касается строки, помеченной
/* Line X */
, которая является двусмысленной объявления для объекта или функции. Предложение о том, что регулирует эту двусмысленность - это пункт 8.2 [dcl.ambig.res], который гласит:Неоднозначность, возникающая из-за сходства между функциональным стилем cast и декларация, упомянутая в 6.8 [stmt.ambig] [..]
В соответствии с этим пунктом есть два возможные интерпретации объявления в строке
X
:
- Объявление
latt
объявляет функцию с возвращаемым значением введитеLattice
и возьмите три аргумента. Тип первых двух аргументыPoint
, и за каждым из этих аргументов следует имя параметра в резервных круглых скобках. Тип третьего аргумент не может быть определен, потому что он является буквальным.. Это будет приводят к синтаксической ошибке.- Объявление решетки объявляет объект, потому что другой вариант (объявление функции) приведет к ошибка синтаксиса. Обратите внимание, что последнее предложение перед "[Примечание:" не является много помощи, потому что обе опции являются декларациями.
Стив Адамчик: несколько человек ответили на это сообщение comp.std.С++ говорят, что они не видели проблемы.
Оригинал плакат ответил:
Я не могу ничего сделать, но соглашусь с вашей аргументацией. Таким образом, существует только одна правильная интерпретация пункта 8.2 [dcl.ambig.res] пункт 1, но я должен сказать, что с некоторой переформулировкой пункт может быть сделано намного яснее, как явно заявить, что весь декларация должна быть принята во внимание и что декларации функций предпочтительнее над объявлениями объектов.
Я хотел бы предложить следующее в качестве замены текущего пункт 8.2 [dcl.ambig.res], пункт 1:
Неоднозначность, возникающая из-за сходства между личным стилем и декларация, упомянутая в 6.8 [stmt.ambig] [...]
Рабочая группа сочла, что нынешняя формулировка достаточно ясна.