对象构造/转发函数声明歧义
-
21-09-2019 - |
题
Observation: the codes pasted below were tested only with GCC 4.4.1, and I'm only interested in them working with GCC.
你好,
我不止几次偶然发现了一个我不理解的对象构造语句,直到今天我才注意到它带来了什么歧义。我将解释如何重现它,并想知道是否有办法修复它(允许 C++0x)。就这样吧。
假设有一个类,其构造函数仅采用一个参数,并且该参数的类型是另一个具有默认构造函数的类。例如。:
struct ArgType {};
class Class
{
public:
Class(ArgType arg);
};
如果我尝试构造一个类型的对象 Class
在堆栈上,我得到了一个歧义:
Class c(ArgType()); // is this an object construction or a forward declaration
// of a function "c" returning `Class` and taking a pointer
// to a function returning `ArgType` and taking no arguments
// as argument? (oh yeh, loli haets awkward syntax in teh
// saucecode)
我说这是一个对象构造,但编译器坚持认为它是函数体内的前向声明。对于仍然不明白的人,这里有一个完整的示例:
#include <iostream>
struct ArgType {};
struct Class {};
ArgType func()
{
std::cout << "func()\n";
return ArgType();
}
int main()
{
Class c(ArgType());
c(func); // prints "func()\n"
}
Class c(ArgType funcPtr()) // Class c(ArgType (*funcPtr)()) also works
{
funcPtr();
return Class();
}
好了,例子已经够多了。任何人都可以帮助我解决这个问题,而不会做出任何太反惯用的东西(我是一个库开发人员,人们喜欢惯用的库)?
- 编辑
没关系。这是一个骗局 最令人烦恼的解析:为什么不 A a(());工作?.
谢谢,履行机构。
其他提示
基于“允许 C++0x”,正确的答案(可能)是将定义更改为:
Class c(ArgType {});
简单、直接,将负担完全放在库的用户身上,而不是作者身上!
编辑:是的,该构造函数被调用——C++ 0x 添加了列表初始化作为界定初始值设定项列表的明确方式。它不能像您的示例中那样被错误解析,但否则含义与使用括号时大致相同。看 N3000, ,§8.5.4/3 下的第三个要点。您可以编写一个构造函数来接收初始值设定项列表作为单个参数,或者初始值设定项列表中的项目可以单独与构造函数参数进行匹配。
不隶属于 StackOverflow