构造函数在 C++ 中是否有“类型”,因为它是一个特殊的成员函数

问题描述 投票:0回答:3

我最近了解到在C++中构造函数没有名称以及关于它们的其他一些事情。我还知道函数在 C++ 中有一种称为“函数类型”的类型。例如, void func(int) { }

在上面的代码片段中,
func

具有

函数类型
void (int)
现在,我想知道,既然构造函数是特殊的成员函数,那么它们是否也有像上面所示的类型。例如,假设我们有:

struct Name { Name(int) { } };

上面所示的构造函数是否也像普通函数或普通成员函数一样具有
函数类型

?如果是,那么我们如何找到该类型。就像我们可以在普通函数上使用 decltype 一样,是否可以在构造函数上使用

decltype
来查找其类型。
    

c++ function types constructor language-lawyer
3个回答
7
投票
是否允许在构造函数上使用
decltype

来查找其类型


这是不允许的。主要是因为无法“命名构造函数”。一个常见的用词不当是像
Name(0)

new Name(0) 这样的表达式调用构造函数。但事实并非如此

func(0)
。构造函数永远不会被我们直接调用,而是总是由需要生成新对象的语言构造间接调用。

[班级.ctor.将军]

1

...构造函数没有名称。

2 构造函数用于初始化其类类型的对象。因为构造函数没有名称,所以在名称查找期间永远找不到它们;然而,使用函数符号([expr.type.conv])的显式类型转换将导致调用构造函数来初始化对象。 [注 1:语法看起来像是构造函数的显式调用。 — 尾注]

因为我们无法命名它们,所以我们无法使用像decltype

这样的内省机制来检查它们。因此,该标准没有为构造函数指定“类型”,因为严格符合标准的程序无法检查所述类型。

构造函数也不能拥有签名(如标准所定义),因为根据定义,签名包括函数名称(并且构造函数,如前所述,是无名的)。


[defns.signature.member]

签名

⟨类成员函数⟩名称、参数类型列表、函数所属的类、cv限定符(如果有)、ref限定符(如果有)和尾部requires子句(如果有)

C++ 中的构造函数有“类型”吗

0
投票
是的,在 C++23 中,它们确实有类型,但在已发布的 C++20 中,它们没有类型,如下所述。这是由于

CWG2479

的状态为
DRWP

C++23

来自

dcl.fct

在声明 T D 中,T 可以为空

,D 具有以下形式

D1 ( parameter-declaration-clause ) cv-qualifier-seqopt    ref-qualifieropt noexcept-specifieropt attribute-specifier-seqopt trailing-return-typeopt 派生声明符类型列表确定如下: * * 函数类型声明的返回类型U确定如下:

如果存在 Trailing-return-type,则 T 应为单个类型说明符 auto,U 为由 Trailing-return-type 指定的类型。

否则,如果声明声明了转换函数,请参阅[class.conv.fct]。
  • 否则,U就是T。 D 中 declarator-id 的类型是“parameter-type-list cv-qualifier-seqopt ref-qualifieropt 返回 U 的衍生声明符类型列表 noexceptopt 函数”,其中
  • D 中 declarator-id 的类型为“parameter-type-list cv-qualifier-seqopt ref-qualifieropt 返回 U 的衍生声明符类型列表 noexceptopt 函数”,其中
  • the optional noexcept is present if and only if the exception specification ([except.spec]) is non-throwing.
  • 可选的 attribute-specifier-seq 与函数类型相关。
    
    任一形式的类型都是函数类型。

注意 C++23 中对 T 可能为空

的强调,这意味着现在构造函数具有类型。

C++20 在 C++20 中,来自

dcl.fct

在声明 T D 中,其中 D 具有以下形式

    D1 ( parameter-declaration-clause ) cv-qualifier-seqopt    ref-qualifieropt noexcept-specifieropt attribute-specifier-seqopt
在声明 T D 中,其中 D 具有以下形式

    D1 ( parameter-declaration-clause ) cv-qualifier-seqopt    ref-qualifieropt noexcept-specifieropt attribute-specifier-seqopt trailing-return-type
任何一种形式的类型都是函数类型。
  1. (强调我的)
这里注意
T

之前

CWG2476

不允许为空
    
类的构造函数永远不会被显式调用。您使用类似

new Name(5)

-3
投票
return

语句。

new Name(5)
返回的是对
new
分配的内存的内存引用。
这是通过如下语法给出的:
Name * foo = new Name(5)

foo 是指向已分配的内容的指针,并且可以进行类型检查,因为

Name
 引用类,而不是其构造函数。


© www.soinside.com 2019 - 2024. All rights reserved.