【问题标题】:What is the type of a constructor?构造函数的类型是什么?
【发布时间】:2019-07-26 10:11:36
【问题描述】:

我知道构造函数没有返回类型。虽然我想知道,那么构造函数的类型是什么?构造函数有类型吗?

我试过了

struct A { A() {} };

template <typename A> struct foo;

int main() { foo< decltype(&A::A) > f; }

获取错误(gcc)

prog.cc: In function 'int main()':
prog.cc:5:32: error: taking address of constructor 'constexpr A::A(A&&)'
    5 | int main() { foo< decltype(&A::A) > f; }
      |                                ^
prog.cc:5:35: error: template argument 1 is invalid
    5 | int main() { foo< decltype(&A::A) > f; }
      |                                   ^

...好吧,好吧,我无法获取地址。这也失败了:

int main() { foo< decltype(A::A) > f; }

prog.cc: In function 'int main()':
prog.cc:5:32: error: decltype cannot resolve address of overloaded function
    5 | int main() { foo< decltype(A::A) > f; }
      |                                ^
[...]

这可能只是一个非常令人困惑的错误消息,原因与上述相同(无法获取构造函数的地址),我不知道还能尝试什么..

构造函数的类型是什么?

如果它没有类型,那它是什么?当然不是A (member_function)()

PS:澄清我的困惑:cpprefernce states

构造函数是一个特殊的非静态成员函数 用于初始化其类类型的对象。

我的逻辑是这样的:成员函数有一个类型,构造函数是特殊类型的成员函数,因此它们应该有一个类型。我知道推理是有缺陷的,但为什么呢?

【问题讨论】:

  • @foreknownas_463035818 因为它不是函数...
  • "一个int没有返回类型,它的类型是int"多么传奇
  • 通常“特殊”表示一般规则的一些例外情况,这就是其中之一。另一个是你不能直接调用它,另一个是你不能获取它的地址,还有一个是它没有名称用于名称查找。
  • @SuperSimplePimpleDimple 请保持优雅。称某人为“bufoon”对任何人都没有帮助,并且可能会标记您原本有用的评论。
  • @SuperSimplePimpleDimple 仅仅因为某些东西以与函数相同的方式实现“低级”,并没有说明它的类型。 C++ 类型是一个纯粹的理论概念,不应与常见的 C++ 实现处理它们的方式相混淆。

标签: c++ constructor member-function-pointers name-lookup


【解决方案1】:

我认为 C++ 17 标准中的这些引用将是相关的(15.1 构造函数)

1 构造函数没有名字......

2 构造函数用于初始化其类类型的对象。 因为构造函数没有名称,所以在名称查找过程中永远找不到它们;但是使用显式类型转换 功能符号(8.5.1.3)将导致调用构造函数 初始化一个对象。 [注:用于类对象的初始化 类型见 15.6。 ——尾注]

10 构造函数主体中的 return 语句不应指定 返回值。构造函数的地址不能取。

【讨论】:

  • 能否也加一下:A return statement in the body of a constructor shall not specify a return value. The address of a constructor shall not be taken. --> 11.3.4 6
【解决方案2】:

构造函数实际上没有类型。

标准没有明确说明这一点可能令人惊讶,但由于它们没有名称,不参与名称查找,无法获取其地址并且是没有返回类型的“函数”,因此可以推断。

【讨论】:

  • Constructors effectively do not have types. 我希望大多数编译器将其解释为 void 返回类型。功能上是一样的。
  • @NO_NAME 好点。可能值得检查void 函数是如何转换为程序集的,以及在这种情况下构造函数是否相似。
  • @NO_NAME 在生成的代码中,构造函数可能看起来有点像void-returning 成员函数,是的。但这并不能告诉我们实际 C++ 中的实际类型
  • @NO_NAME 不。我不仅希望而且要求所有编译器都按照标准中的表述来解释它。如果您能找到例外情况,请在此处提供。
  • @user207421 如果您引用标准中的说明构造函数需要返回 void,请写下问题的答案。
【解决方案3】:

如果他们有类型,你能做什么?完全没有。这就是为什么:

如果他们有一个,您也许可以通过获取构造函数的地址来获取指向构造函数的指针(如果立即在语法上使用结果来初始化正确类型的指针,那么获取重载实体的地址是明确的)。

如果他们有指向他们的指针,你能做什么?什么都没有。

他们没有名字。指向A 的构造函数的非空指针将始终指向&amp;A::A。不妨去掉指针样板,直接“调用构造函数”。

【讨论】: