我最近了解到构造函数没有名字。我还知道函数有一种称为“函数类型”的类型。例如,
void func(int)
{
}
在上面的代码片段中,
func
具有
函数类型
void (int)
。现在,既然构造函数是特殊的成员函数,那么它们是否也有像上面所示的类型呢?例如,假设我们有:
struct Name
{
Name(int)
{
}
};
上面所示的构造函数是否也像普通函数或普通成员函数一样具有函数类型
?如果是,那么我们如何找到该类型呢?是否允许在构造函数上使用 decltype
来查找其类型,就像对普通函数所做的那样?
decltype
来查找其类型
这是不允许的。主要是因为无法“命名构造函数”。一个常见的用词不当是像
Name(0)
或 new Name(0)
这样的表达式调用构造函数。但事实并非如此
func(0)
。构造函数永远不会被我们直接调用,而是总是由需要生成新对象的语言构造间接调用。
[班级.ctor.将军]
1...构造函数没有名称。
2 构造函数用于初始化其类类型的对象。因为构造函数没有名称,所以在名称查找期间永远找不到它们;然而,使用函数符号([expr.type.conv])的显式类型转换将导致调用构造函数来初始化对象。 [注 1:语法看起来像是构造函数的显式调用。 — 尾注]
因为我们无法命名它们,所以我们无法使用像
这样的内省机制来检查它们。因此,该标准没有为构造函数指定“类型”,因为严格符合标准的程序无法检查所述类型。decltype
构造函数也不能拥有签名(如标准所定义),因为根据定义,签名包括函数名称(并且构造函数,如前所述,是无名的)。
[defns.signature.member]
签名C++ 中的构造函数有“类型”吗⟨类成员函数⟩名称、参数类型列表、函数所属的类、cv限定符(如果有)、ref限定符(如果有)和尾部requires子句(如果有)
这是CWG2476
,其状态为
DRWP
(意味着已在 C++26 工作草案中接受),这也使得构造函数具有类型。注意已发布
c++23不允许构造函数具有类型: C++23 这里
T
T D
不允许为空,这意味着 ctor 在已发布的 c++23 中没有类型。
来自dcl.fct:
T D
,其中CWG2476在声明 T D 中,其中 D 具有以下形式
D
- 具有以下形式
D1 ( parameter-declaration-clause ) cv-qualifier-seqopt ref-qualifieropt noexcept-specifieropt attribute-specifier-seqopt
D1 ( parameter-declaration-clause ) cv-qualifier-seqopt ref-qualifieropt noexcept-specifieropt attribute-specifier-seqopt trailing-return-type
- 可选的 attribute-specifier-seq 属于函数类型。
任何一种形式的类型都是函数类型。
在
- 注意这里
T
之前不允许为空,这意味着构造函数在c ++ 23中没有类型。
CWG2476 在 C++26 的T
[在 2024 年 3 月的会议上被接受为 DR 。]
9.3.4.6 [dcl.fct] 第 1 段的更改如下:
在声明 T D
- 中,T 可以为空
,D 的形式为:任何一种形式的类型都是函数类型
D1 ( parameter-declaration-clause ) cv-qualifier-seqopt ref-qualifieropt noexcept-specifieropt attribute-specifier-seqopt trailing-return-typeopt
。注意上面 CWG 中添加的对 T 可能为空
的强调,这意味着 ctor
Name::Name(int)
确实有一个类型。
类的构造函数永远不会被显式调用。您使用类似
new Name(5)
return
语句。
new Name(5)
返回的是对new
分配的内存的内存引用。这是通过如下语法给出的:Name * foo = new Name(5)
foo 是指向已分配的内容的指针,并且可以进行类型检查,因为
Name
引用类,而不是其构造函数。