此问题在此处已有答案:
Can typedef names be used to declare or define constructors?(2个答案)
Using class alias for its constructor definition [duplicate](1个答案)
14小时前就关门了。
参加本课程:
class Foo {
public:
using MyType = Foo;
MyType* m = nullptr; //ok
MyType* functor() { //ok
return nullptr;
}
MyType() = default; //error
~MyType() = default; //error
};
为什么可以对成员使用别名,而不能对构造函数或析构函数使用别名?
2条答案
按热度按时间a9wyjsp71#
因为它被标记为
language-lawyer
,让我们看看标准有什么要说的。从class.ctor.gen(https://eel.is/cdraft/class.ctor)开始,着重号为:
如果声明符是ptr-declarator(parameter-declaration-clause)noexcept-specifieropt attribute-specifier-seqopt形式的函数声明符([dcl.fct]),则声明符声明一个构造函数,其中ptr-declarator只包含一个id-expression、一个可选的属性说明符seq和可选的括号,并且id-expression具有以下形式之一:
(1.1)在友元声明([class.friend])中,id表达式是命名构造函数([class.qual])的限定id;
(1.2)否则,在属于类或类模板的成员规范的成员声明中,id表达式是直接包含实体的注入类名([class.pre]);
(1.3)否则,id表达式是限定id,其unqualified-id是其查找上下文的注入类名。
对于为什么一个名字别名对于声明构造函数是无效的主题,特别是(1.2)是相关的。它声明 * id表达式是injected-class-name[..]*。后者在class.pre(https://eel.is/cdraft/class.pre)中定义:
1.类是一种类型。它的名称在它的作用域中成为类名([class.name])。
[..]
1.类名也被绑定在类(模板)本身的作用域中;这称为injected-class-name。为了进行访问检查,injected-class-name被视为公共成员名。[..]
这非常清楚地表明,injected-class-name 就是最初用来声明类的名称,在措辞上不允许使用别名。
这遵循您在类模板中看到的相同机制:
现在,没有名为
C
的类,C
是一个模板,所以你通常会说C<T> foo();
。但是正如[class.pre]中所述,在类定义的作用域中引入了一个 class-name,它引用了实际的类型。所以,即使在任何地方都没有C
类,class-nameC
可以用作C<T>
的简写,并且在构造函数和析构函数的情况下,是引用它的唯一方式,因为它们的声明不允许您使用任何类型ID,而是仅class-name。bihw5rsg2#
m
是一个指向一个类型示例的指针,它是有别名的。functor()
返回一个指向一个类型示例的指针,该类型是有别名的。但是构造函数/析构函数本身并不是一个类型,所以不能为它们使用类型别名。它们必须以所属的类型命名。这就是语法的工作方式