我不明白为什么编译


80

我当然会缺少一些东西,但是我不明白为什么会这样编译(同时使用g ++和clang ++):

struct A
{
};
struct B
{
};

int main()
{
  A a(B);
}

首先,B是一个类型……不是一个值。我应该如何解释此代码?


37
这被称为“
令人烦恼的

8
@alterigel真的吗?在这种情况下,没有歧义。它只能是一个函数声明。A a(B());可能不是变量定义或函数声明。
胡桃木

8
您会惊讶地知道它struct A{}; int main() { A(foo); } 按原样编译,即使foo没有命名。
Ayxan

20
@alterigel-这不是最烦人的解析。查看您链接到的页面上的示例。这只是一个函数声明。
皮特·贝克尔,

3
@PeteBecker,可能最好解释一下为什么这不是MVP,而不仅仅是断言它不是MVP,我认为胡桃木已经在上面做了。
JPhi1618

Answers:


84

它被解释为一个名为的函数的声明,该函数a采用type的一个参数B并返回A


5
这就是为什么它是Most and Vexing。一个解决方案:(不是因为它暴露了不良的构造,所以实际上并不能解决任何问题)A a{B};
user4581301 19/12/3

23
@ user4581301-这不是最烦人的解析。它只是一个函数声明。
皮特·贝克尔,

23
因此,原来这只是一个大多伤脑筋解析...
MooseBoys

11
关于它的最奇怪的是,C ++不允许嵌套功能,但确实允许函数内声明。
The_Sympathizer '19

6
在C ++中增加对嵌套函数的支持听起来很不错。它们不仅有用,还会将这种奇怪的疣变成合理的设计:)
杰里米·弗里斯纳

15

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

这是有效的,因为在函数定义中允许使用与函数定义相反的函数声明。


13

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

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

这里是更多信息:

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


12
我认为这不应该称为“ 最烦人的解析 ”。它只是C中也存在的一种常见的函数声明。没有歧义的解决方案是必需的,因为该行只能是一个函数声明,没有别的。查看您的链接。例子都与此不同。
胡桃木

3
的确如此,但这与最烦人的解析有关。只是这还包括一个拼写错误,其中单独使用类型名称而不是变量或构造函数调用,这可能是原始意图。
Miral

1
是的,即使问题中的实际情况只是“轻微麻烦解析”,“多数麻烦解析”在这种情况下也是一个有用的答案。
jpa

1
@wlanut:struct A { };即使某些编译器允许,空结构在标准C中也不有效。放下牙套,那里不会有问题。同样,在C语言中,声明或定义struct A不会创建类型名称A(必须在该名称之前加上struct,或typedef struct A A;A不使用该struct前缀的情况下添加一个地方)。同样在C语言中,函数声明没有其他解析方法- type name(...);根本不可能使用变量定义;它始终是函数声明(或无效)。在这个问题的代码是无效的C.
乔纳森·莱弗勒
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.