В грамматике есть двусмысленность, связанная с expression-statements and declarations: An expression-statementс a в function-style explicit type conversion качестве крайнего левого подвыражения может быть неотличимо от a, declarationгде первое declaratorначинается с a (. В этих случаях используется statementфайл declaration.
[ Note: Если statementсинтаксически не может быть a declaration, двусмысленности нет, поэтому это правило не применяется. Вся statementпотребность Мощь быть исследованы , чтобы определить , является ли этот случай. Это решает смысл многих примеров. [ Example: Предполагая , что T это simple-type-specifier,
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
В последнем примере выше, gкоторый является указателем на T, инициализируется на double(3). Это, конечно, плохо сформировано по семантическим причинам, но это не влияет на синтаксический анализ. ] — end example
Остальные случаи есть declarations. [ Example:
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
Устранение неоднозначности чисто синтаксическое; то есть значение имен, встречающихся в таком утверждении, вне зависимости от того, есть они type-names или нет, обычно не используется и не изменяется в результате устранения неоднозначности. Шаблоны классов создаются по мере необходимости, чтобы определить, является ли полное имя type-name. Устранение неоднозначности предшествует синтаксическому анализу, и утверждение, устраняемое как декларация, может быть неверно сформированной декларацией. Если во время синтаксического анализа имя в параметре шаблона связано иначе, чем оно было бы связано во время пробного синтаксического анализа, программа имеет неправильный формат. Диагностика не требуется. [ Note: Это может произойти только в том случае, если имя объявлено ранее в объявлении. ] [ — end note Example:
struct T1 { T1 operator()(int x) { return T1(x); } int operator=(int x) { return x; } T1(int) { } }; struct T2 { T2(int){ } }; int a, (*(*b)(T2))(int), c, d; void f() { // disambiguation requires this to be parsed as a declaration: T1(a) = 3, T2(4), // T2 will be declared as a variable of type T1, but this will not (*(*b)(T2(c)))(int(d)); // allow the last part of the declaration to parse properly, // since it depends on T2 being a type-name }
— end example ]