Ответ 1
Насколько я могу судить об этом, мы рассмотрим в проекте стандартного раздела С++ 6.8
Ambiguity, в котором говорится, что между выражениями выражения и объявлениями может быть неопределенность и говорит:
Существует двусмысленность в грамматике, включающая выражения-выражения и объявления: выражение выражение с функцией-стиль явное преобразование типа (5.2.3), поскольку его самое левое подвыражение может быть неотличимы от декларации, где начинается первый декларатор с. (В этом случае утверждение является объявлением. [Примечание: для устранить неоднозначность, все выражение, возможно, придется изучить определить, является ли это выражением-выражением или декларацией. Эта неоднозначно много примеров. [Пример: предполагая, что T является простой тип-спецификатор (7.1.6),
и дает следующие примеры:
T(a)->m = 7; // expression-statement
T(a)++; // expression-statement
T(a,5)<<c; // expression-statement
T(*d)(int); // declaration
T(e)[5]; // declaration
T(f) = { 1, 2 }; // declaration
T(*g)(double(3)); // declaration
а затем говорит:
Остальные случаи - это объявления. [Пример:
class T { // ... public: T(); T(int); T(int, int); }; T(a); // declaration T(*b)(); // declaration T(c)=7; // declaration T(d),e,f=3; // declaration extern int h; T(g)(h,2); // declaration
-end example] -end note]
Кажется, что этот случай попадает в примеры объявления, в частности, последний пример, похоже, делает случай в OP, поэтому gcc
будет правильным.
Соответствующий раздел, упомянутый выше 5.2.3
Явное преобразование типа (функциональная нотация) говорит:
[...] Если указанным типом является тип класса, тип класса должен быть полным. Если выражение list указывает более чем одно значение, тип должен быть классом с соответствующим объявленным конструктором (8.5, 12.1), и выражение T (x1, x2,...) эквивалентно по существу объявлению T t (x1, x2,...); для некоторых придумал временную переменную t, результатом которой является значение t в качестве значения pr.
и 8.3
Значение деклараторов, в котором говорится:
В объявлении T D, где D имеет вид
( D1 )
тип содержащегося идентификатора declarator-id такой же, как у содержащий декларатор-id в объявлении
T D1
Круглые скобки не изменяют тип встроенного идентификатора декларатора, но они могут изменить привязку сложных деклараторов.
Обновить
Я изначально использовал N337, но если мы посмотрим на N4296, раздел 6.8
был обновлен теперь он включает следующее примечание:
Если утверждение не может синтаксически быть объявлением, нет никакой двусмысленности, поэтому это правило не применяются.
что означает, что gcc
неверно, так как:
foo x ("bar")("baz");
не может быть допустимым объявлением, я изначально интерпретировал абзац 2
, говоря, что если вы начинаете с любого из следующего, то это объявление, которое, возможно, также интерпретируется и разработчиком gcc
.
Я должен был более подозрительно относиться к параграфу 2
, так как единственная нормативная часть параграфа 2
действительно ничего не говорила в отношении параграфа 1
и, по-видимому, помещает требование на пример, который не является нормативным. Мы можем видеть, что эта формулировка с параграфом 2
теперь является фактически запиской, которая имеет гораздо больше смысла.
Как T.C. ниже, пункт 2
на самом деле никогда не был нормативным, он появился именно так и он связан с изменением, которое зафиксировало его.