可以使用typedef名称来声明或定义构造函数吗?

时间:2012-07-13 22:03:21

标签: c++ language-lawyer

Standardese:

[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。

我的分析是否正确,所有这些编译器都错了吗?

2 个答案:

答案 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等中不起作用,有没有办法在其他编译器中做到这一点?