简体   繁体   English

对象构造/转发函数声明歧义

[英]Object construction/Forward function declaration ambiguity

Observation: the codes pasted below were tested only with GCC 4.4.1, and I'm only interested in them working with GCC.

Hello, 你好,

It wasn't for just a few times that I stumbled into an object construction statement that I didn't understand, and it was only today that I noticed what ambiguity was being introduced by it. 我偶然发现了一些我不理解的对象构造语句,而且直到今天我才注意到它引入的歧义。 I'll explain how to reproduce it and would like to know if there's a way to fix it (C++0x allowed). 我将解释如何重现它,并想知道是否有办法解决它(允许C ++ 0x)。 Here it goes. 在这里。

Suppose there is a class whose constructor takes only one argument, and this one argument's type is another class with a default constructor. 假设有一个类,其构造函数只接受一个参数,而这个参数的类型是另一个具有默认构造函数的类。 Eg: 例如:

struct ArgType {};

class Class
{
public:
    Class(ArgType arg);
};

If I try to construct an object of type Class on the stack, I get an ambiguity: 如果我尝试在堆栈上构造类型为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)

I say it's an object construction, but the compiler insists it's a forward declaration inside the function body. 我说这是一个对象构造,但编译器坚持认为它是函数体内的前向声明。 For you who still doesn't get it, here is a fully working example: 对于仍然没有得到它的人来说,这是一个完全有效的例子:

#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();
}

So well, enough examples. 好吧,足够的例子。 Anyone can help me get around this without making anything too anti-idiomatic (I'm a library developer, and people like idiomatic libraries)? 任何人都可以帮助我解决这个问题,而不会产生任何过于反本能的东西(我是图书馆开发人员,而人们喜欢习惯性的图书馆)?

-- edit - 编辑

Never mind. 没关系。 This is a dupe of Most vexing parse: why doesn't A a(()); 这是最令人烦恼的解析:为什么不是A(()); work? 工作? .

Thanks, sbi. 谢谢,sbi。

This is known as "C++'s most vexing parse". 这被称为“C ++最令人烦恼的解析”。 See here and here . 看到这里这里

Based on the "C++0x allowed", the right answer is (probably) to change the definition to: 基于“C ++ 0x allowed”,正确的答案是(可能)将定义更改为:

Class c(ArgType {});

Simple, straightforward and puts the burden entirely on the user of the library, not the author! 简单,直接,并将负担完全放在库的用户身上,而不是作者!

Edit: Yes, the ctor is invoked -- C++ 0x adds List-Initialization as an unambiguous way to delimit initializer lists. 编辑:是的,调用ctor - C ++ 0x添加List-Initialization作为分隔初始化列表的明确方法。 It can't be mis-parsed like in your sample, but otherwise the meaning is roughly the same as if you used parentheses. 它不能像你的样本那样被错误解析,但其他含义与你使用括号大致相同。 See N3000 , the third bullet point under §8.5.4/3. N3000 ,§8.5.4/ 3下的第三个要点。 You can write a ctor to receive an initializer list as a single argument, or the items in the initializer list can be matched up with the ctor arguments individually. 您可以编写一个ctor来接收初始化列表作为单个参数,或者初始化列表中的项可以单独与ctor参数匹配。

Let's simplify a little. 让我们简化一下。

int f1();

What's that? 那是什么? The compiler (and I) say it's a forward declaration for a function returning an integer. 编译器(和我)说它是返回整数的函数的前向声明。

How about this? 这个怎么样?

int f2(double );

The compiler (and I) say it's a forward declaration for a function taking a double argument and returning an int. 编译器(和我)说它是一个带有double参数并返回int的函数的前向声明。

So have you tried this: 所以你试过这个:

ClassType c = ClassType(ArgType());

Check out the c++ faq lite on constructors for explanations and examples 查看构造函数上的c ++ faq lite以获取解释和示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM