我肯定是遗漏了什么,但我不明白为什么这个代码可以通过编译(无论是使用g++还是clang++):
struct A
{
};
struct B
{
};
int main()
{
A a(B);
}
首先,B
是一种类型,而不是一个值。我该如何解释这段代码?
我肯定是遗漏了什么,但我不明白为什么这个代码可以通过编译(无论是使用g++还是clang++):
struct A
{
};
struct B
{
};
int main()
{
A a(B);
}
首先,B
是一种类型,而不是一个值。我该如何解释这段代码?
其实是一个名为 a
的函数声明,它接受一个类型为 B
的参数并返回一个 A
类型的值。
A a{B};
- user4581301这只是一个函数声明,声明了a
为返回A
类型、并接受一个B
类型未命名参数的函数。
这是合法的,因为在函数定义中允许函数声明而非函数定义。
这个问题被称为最具挑战性的解析。行A a(B);
可以被解释为声明一个名为a
的函数,返回类型为A
的对象,并带有一个未命名的类型为B
的参数。
避免此问题的一种方法是使用C++11中引入的统一初始化语法,其中使用花括号代替括号:A a{B};
会返回错误。现在将该行解释为变量声明并用B
进行初始化,而B
是一个类型而不是一个值。
这里有更多信息:
struct A { };
在标准C中是无效的,即使有些编译器允许。去掉大括号就不会有问题了。此外,在C语言中,声明或定义struct A
并不会创建类型名A
(必须在A
被使用时加上struct
前缀,或者在A
之前添加typedef struct A A;
)。同样在C语言中,函数声明没有其他解析方式——使用type name(...);
永远不能成为变量定义;它总是一个函数声明(或无效)。问题中的代码在C语言中是无效的。 - Jonathan Leffler
A a(B());
,后者可能是一个变量定义或函数声明。 - walnutstruct A{}; int main() { A(foo); }
即使foo
没有指定任何内容,也可以如此编译。 - Ayxan Haqverdili