可能重复:
Why is it an error to use an empty set of brackets to call a constructor with no arguments?
Most vexing parse: why doesn't A a(()); work?
这个让我发疯。也许它太简单了。
struct Foo
{
Foo() {}
Foo(const Foo& f) {}
void work() {}
};
int main()
{
Foo f( Foo() );
f.work();
}
GCC 4.6给了我:
error: request for member ‘work’ in ‘f’, which is of non-class type ‘Foo(Foo (*)())’
在省略复制操作后,有效代码可能如下所示:
int main()
{
Foo f;
f.work();
}
但为什么我不能打电话给work()
??
编辑:
是的,重复(见下文)。在搜索时没有找到原始帖子,因为这个症状的来源位于我没想到的地方。
答案 0 :(得分:3)
因为Foo f( Foo() );
是函数声明。
我想你想要:Foo f;
或者如果你想复制构造:
Foo f( (Foo()) );
答案 1 :(得分:1)
f实际上是main函数中的函数声明。 试试
Foo f((Foo())); // to make the definition of f explicit enough.
答案 2 :(得分:1)
n3337 8.2
功能风格之间相似性产生的模糊性 在6.8中提到的演员和声明也可以在上下文中出现 声明。在这种情况下,选择是在一个函数之间 声明与参数周围的一组冗余括号 具有函数样式转换的名称和对象声明 初始化。正如6.8中提到的含糊不清一样 解决方案是考虑任何可能是a的构造 声明声明。 [注意:声明可以明确 由非函数式转换消除歧义,由=表示 初始化或删除周围的冗余括号 参数名称。 - 尾注] [例子:
struct S {
S(int);
};
void foo(double a) {
S w(int(a));
//function declaration
S x(int());
//function declaration
S y((int)a);
//object declaration
S z = int(a);
//object declaration
}
- 结束示例]
答案 3 :(得分:1)
C ++解析器将Foo f(Foo());
表达式解释为具有签名Foo(Foo(*)())
的函数声明,即返回Foo的函数并将函数指针指向返回Foo的函数。在参数周围添加显式括号,如Foo f((Foo()));
,将解决歧义。但实际上只考虑Foo f;
来避免冗余代码。