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++ 最令人烦恼的解析”。看 这里这里.

其他提示

让我们简单一点。

int f1();

那是什么?编译器(和我)说这是返回整数的函数的前向声明。

这个怎么样?

int f2(double );

编译器(和我)说这是一个带有双参数并返回 int 的函数的前向声明。

那么你有没有尝试过这个:

ClassType c = ClassType(ArgType());

查看 c++ 常见问题解答精简版 构造函数 为了 解释 和例子

基于“允许 C++0x”,正确的答案(可能)是将定义更改为:

Class c(ArgType {});

简单、直接,将负担完全放在库的用户身上,而不是作者身上!

编辑:是的,该构造函数被调用——C++ 0x 添加了列表初始化作为界定初始值设定项列表的明确方式。它不能像您的示例中那样被错误解析,但否则含义与使用括号时大致相同。看 N3000, ,§8.5.4/3 下的第三个要点。您可以编写一个构造函数来接收初始值设定项列表作为单个参数,或者初始值设定项列表中的项目可以单独与构造函数参数进行匹配。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top