【发布时间】:2012-07-13 22:03:20
【问题描述】:
标准:
[class.ctor] 12.1/1 说
一种特殊的声明符语法用于声明或定义构造函数。语法使用:
- 一个可选的 decl-specifier-seq,其中每个 decl-specifier 是 function-specifier 或 constexpr,
- 构造函数的类名,以及
——一个参数列表
按这个顺序。
[class.name] 9.1/4 说
一个 typedef-name (7.1.3) 命名一个类类型,或一个 cv 限定 其版本,也是一个类名。如果一个 typedef-name 命名一个 在需要 class-name 的地方使用 cv 限定的类类型, cv 限定符被忽略。 typedef-name 不得用作 类头中的标识符。
还有 [expr.prim.general] 5.1.1/8 说
其中class-name :: class-name使用,两个class-name是指 对于同一个类,这个符号命名构造函数(12.1)。
应用:
在我看来,这似乎是说应该允许使用 typedef 名称声明构造函数(尽管 12.1/1 不使用斜体 class-name)。
例如,给定:
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。
我的分析是否正确,所有这些编译器都错了吗?
【问题讨论】:
-
(1) 似乎被 §12.1/3 排除(“A typedef-name 不应用作构造函数声明的 declarator-id 中的类名。”)跨度>
-
您应该澄清您所指的标准的哪个版本,C++03(又名 ISO/IEC 14882:2003)或 C++11(ISO/IEC 14882:2011);我祈祷你不是指 C++98。
-
@AdamRosenfield C++11,但我不认为 C++11 在这方面有任何改变。
-
@AdamRosenfield 目前我正在查看文档 N3337(2012 年 1 月的草稿)。我找到了包含相同句子的 C++98 版本,所以这似乎没有改变(与 amalp.blogspot.de/2007/07/typedef-name-as-identifier-of.html 声称的相反)。
标签: c++ language-lawyer