我不明白为什么会编译

Pic*_*ent 81 c++ syntax declaration most-vexing-parse

我当然错过了一些东西,但我不明白为什么会编译(同时使用 g++ 和 clang++):

struct A
{
};
struct B
{
};

int main()
{
  A a(B);
}
Run Code Online (Sandbox Code Playgroud)

首先,B是一种类型……而不是值。我应该如何解释这段代码?

Bri*_*ian 85

它被解释为一个名为 的函数的声明a,它接受一个类型为 的参数B并返回A

  • @user4581301——这不是最令人烦恼的解析。它只是一个函数声明。 (23认同)
  • 最奇怪的部分是 C++ 不允许嵌套函数,但_确实_允许在函数内声明。 (11认同)
  • 听起来像是向 C++ 添加对嵌套函数的支持的一个很好的动机;它们不仅有用,还能把这个奇怪的问题变成一个合理的设计:) (6认同)
  • 这就是为什么它是最令人烦恼的。一个解决方案:(并不是说它实际上解决了任何问题,因为它暴露了错误的结构)`A a{B};` (5认同)
  • @Brian“有点违反直觉”可能是 C++ 的座右铭:)。至于前向声明,我只会认为它们不支持本地函数,并称之为完成。 (3认同)
  • @The_Sympathizer 就像 C++ 中的其他所有内容一样,它有其有效的用例。 (2认同)

mac*_*e_1 15

它只是一个函数声明,声明a它是一个返回A并接受一个未命名的 type 参数的函数B

它是有效的,因为在函数定义中允许使用函数声明而不是函数定义。


小智 13

这个问题被称为最令人头疼的解析。该行A a(B);可以解释为一个函数的声明,该函数名为a返回一个类型的对象A并采用一个未命名的类型参数B

避免此问题的一种方法是使用C++11 中引入的统一初始化语法,其中包括使用大括号而不是括号:A a{B};返回错误。该行现在被解释为一个用 初始化的变量声明B,它是一个类型而不是一个值。

以下是更多信息:

最烦人的解析:如何发现并快速修复

  • 我认为这不应该被称为“*最令人烦恼的解析*”。它只是一个常见的函数声明,因为它也存在于 C 中。不需要歧义解析,因为该行只能是函数声明,没有其他内容。看看你的链接。这些例子都与此不同。 (12认同)
  • 虽然这是事实,但它与最令人烦恼的解析有关。只是这还包括一个拼写错误,其中单独使用类型名称而不是变量或构造函数调用,这可能是最初的意图。 (3认同)