[class.ctor] 12.1 / 1说
特殊的声明符语法用于声明或定义构造函数。语法使用:
- 一个可选的 decl-specifier-seq ,其中每个 decl-specifier 是函数说明符或 constexpr < /强>,
- 构造函数的类名和
- 参数列表
按顺序。
[class.name] 9.1 / 4说
typedef-name (7.1.3),用于命名类类型或cv限定 其版本也是类名。如果名为a的 typedef-name 在需要 class-name 的地方使用cv限定的类类型 cv-qualifiers被忽略。 typedef-name 不得用作 class-head 中的标识符。
另外[expr.prim.general] 5.1.1 / 8说
使用 class-name :: class-name ,并且两个类名引用 对于同一个类,这个表示法命名构造函数(12.1)。
在我看来,应该允许使用typedef名称来声明构造函数(尽管事实上12.1 / 1不使用斜体类名)。
例如,给定:
struct Foo;
typedef Foo Bar;
然后
struct Foo { Bar() {} }; // defines Foo's constructor. - 1
或代之以
struct Foo;
struct Foo { Foo() };
typedef Foo Bar;
然后
Foo::Bar() {}; // defines Foo's constructor - 2
或
Bar::Bar() {}; // defines Foo's constructor - 3
或
Bar::Foo() {}; // defines Foo's constructor - 4
任何这些都应该是合法的。然而,似乎没有人接受定义2或3,MSVC接受1,MSVC,clang和gcc都接受4。
我的分析是否正确,所有这些编译器都错了吗?
答案 0 :(得分:14)
§12.1/ 3 the working draft N3337 (Feb 2012)个州
typedef-name 不得用作构造函数声明的 declarator-id 中的 class-name 。
这排除了(1)。
§12.1/ 1似乎对声明和定义都使用了“声明”一词:
特殊的声明符语法用于声明或定义构造函数。 [......]在这样的声明中,[...]
(未明确提及“定义”)。我认为这是否适用于类外定义或仅适用于内联定义有点不清楚。如果它适用于所有类型的定义,这也将排除(2)和(3)。 (4)在任何情况下都应合法。
答案 1 :(得分:0)
很烦人的是,它似乎可以在Microsoft C中运行,但不适用于我使用的其他编译器。 特别是在模板中需要时。也许我不知道执行此操作的“符合标准的方式”,但这在模板中确实很有用。
template<class T, class T1, ... /* messy, verbose */ >
class MyTemplate {
protected:
typedef MyTemplate<T,T1, ... /* messy, verbose */ > SimplerName;
// declare a constructor
SimplerName(int arg) { ... }
};
class SubClass
: public MyTemplate<x,y....>
{
public:
SubClass(int arg) : SimplerName(arg) { ... }
}.
也许还有另一个问题,这可能在GCC,Clang等中不起作用,有没有办法在其他编译器中做到这一点?