Standardese:
[class.ctor] 12.1/1 говорит
Для объявления или определения конструктора используется специальный синтаксис декларатора. Синтаксис использует:
- необязательный spec-specifier-seq, в котором каждый спецификатор-спецификатор является либо спецификатором функции, либо constexpr,
- имя класса конструкторов и
- список параметров
в этом порядке.
[class.name] 9.1/4 говорит
Имя typedef-name (7.1.3), которое называет тип класса или cv-квалификацию его версия также является именем класса. Если имя typedef, которое Тип класса cv-qual используется, когда требуется имя класса, cv-квалификаторы игнорируются. Имя typedef не должно использоваться как идентификатор в заголовке класса.
Также [expr.prim.general] 5.1.1/8 говорит
В тех случаях, когда используется имя класса:: class-name, а также имена двух классов к тому же классу, это обозначение называет конструктор (12.1).
Применение:
Мне кажется, что объявление конструктора должно быть разрешено с использованием имен typedef (несмотря на то, что 12.1/1 не использует курсивом имя класса).
Например, данный:
struct Foo;
typedef Foo Bar;
затем
struct Foo { Bar() {} }; // defines Foo constructor. - 1
или вместо этого
struct Foo;
struct Foo { Foo() };
typedef Foo Bar;
затем
Foo::Bar() {}; // defines Foo constructor - 2
или
Bar::Bar() {}; // defines Foo constructor - 3
или
Bar::Foo() {}; // defines Foo constructor - 4
Любое из них должно быть законным. Однако никто, кажется, не принимает определения 2 или 3, MSVC принимает 1, а MSVC, clang и gcc все принимают 4.
Правильно ли мой анализ, и все эти компиляторы ошибочны?