C++ 我不明白这是为什么

C++ 我不明白这是为什么,c++,syntax,declaration,most-vexing-parse,C++,Syntax,Declaration,Most Vexing Parse,我当然遗漏了一些东西,但我不明白为什么会编译(同时使用g++和clangg++): 首先,B是一种。。。没有价值。如何解释此代码?它被解释为名为a的函数的声明,它接受一个类型为B的参数并返回A它只是一个函数声明,声明A为返回A的函数,并接受一个类型为B的未命名参数 它是有效的,因为函数定义中允许函数声明而不是函数定义。此问题称为。线A(B)可以解释为名为a的函数的声明,该函数返回a类型的对象,并使用B类型的未命名参数 避免此问题的一种方法是使用C++11中引入的统一初始化语法,该语法包括使用大括

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


首先,
B
是一种。。。没有价值。如何解释此代码?

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

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


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

此问题称为。线
A(B)
可以解释为名为
a
的函数的声明,该函数返回
a
类型的对象,并使用
B
类型的未命名参数

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

以下是更多信息:


这被称为@alterigel,真的吗?在这种情况下,没有歧义。它只能是一个函数声明。它不是
A(B())可以是变量定义或函数声明;int main(){A(foo);}
,即使
foo
没有任何名称。@alterigel——这不是最麻烦的解析。请看您链接到的页面上的示例。这只是一个函数声明。@PeteBecker,最好解释一下为什么这不是MVP,而不是简单地断言它不是MVP,我相信胡桃木已经在上面做了。这就是为什么它是最令人烦恼的。一个解决方案:(并不是说它实际上解决了任何问题,因为它暴露了坏的结构)
A{B}@user4581301——这不是最麻烦的解析。这只是一个函数声明。最奇怪的部分是C++不允许嵌套函数,但允许函数内声明。这听起来是一个很好的动机,它为C++添加嵌套函数的支持;它们不仅有用,还可以将这个奇怪的缺点转化为合理的设计:)@Brian“有点违反直觉”可能是C++的座右铭:)。至于转发声明,我只是认为它们不支持本地函数,并称之为done。我不认为这应该被称为“最麻烦的解析”。这只是一个常见的函数声明,因为它也存在于C中。没有必要进行歧义解决,因为该行只能是一个函数声明,而不是其他任何东西。看看你的链接。这些例子都与此不同。虽然这是事实,但它与最麻烦的解析有关。这还包括一个打字错误,其中一个类型名被单独使用,而不是变量或构造函数调用,这可能是它的初衷。是的,“最麻烦的解析”在这种情况下是一个有用的答案,即使问题中的实际情况只是“稍微麻烦的解析”。@wlanut:the empty structures
struct a{在标准C中无效,即使某些编译器允许。放下支架,就不会有问题了。此外,在C语言中,声明或定义
struct A
不会创建类型名
A
(必须使用
struct
作为前缀,或添加
typedef struct A;
在使用
A
之前的某个位置,而不使用
struct
前缀)。同样在C语言中,函数声明没有其他解析方法——使用
类型名(…)永远不能是变量定义;它始终是一个函数声明(或无效)。问题中的代码在C.@jpa中无效,我在任何地方都找不到任何关于“稍微令人烦恼的解析”的文章。这个名字只是口头的传统吗?我想多读一点。
struct A
{
};
struct B
{
};

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