C++ C++;:奇怪的“事件”;请求Y中非类别类型Z的成员X“;

C++ C++;:奇怪的“事件”;请求Y中非类别类型Z的成员X“;,c++,most-vexing-parse,C++,Most Vexing Parse,使用g++4.6编译的以下程序产生错误 request for member ‘y’ in ‘a2’, which is of non-class type ‘A<B>(B)’ 但在我看来 A<B> a2(B(v)); a2(B(v)); 不能解释为函数声明 有人能给我解释一下发生了什么事吗?我想你被“最烦人的解析”咬了一口,意思是a2(B(v))被解析为函数声明而不是变量声明。如以下代码示例所示: int a (int(v)) { return v; }

使用g++4.6编译的以下程序产生错误

request for member ‘y’ in ‘a2’, which is of non-class type ‘A<B>(B)’
但在我看来

A<B> a2(B(v));
a2(B(v));
不能解释为函数声明


有人能给我解释一下发生了什么事吗?

我想你被“最烦人的解析”咬了一口,意思是
a2(B(v))被解析为函数声明而不是变量声明。

如以下代码示例所示:

int a (int(v)) {
    return v;
}

int main() {
    std::cout << a(5); //prints 5
}
inta(int(v)){
返回v;
}
int main(){

std::cout这是最麻烦的解析的一种情况,编译器将
a2(B(v))
解释为函数的声明。例如:

A
是返回类型
a2
是函数名
B
是参数的类型
v
是参数名

所以,当你在做

std::cout << a1.y.u << " " << a2.y.u << std::endl;

std::cout它是一个函数声明:

A<B> a2(B(v));
//is same as:
A<B> a2(B v);

//consider:
int foo(int v);
int foo(int (v));
a2(B(v));
//同:
a2(bv);
//考虑:
int foo(int v);
内富(内(五));;

在我看来,这似乎是的一个例子。一个更有趣的问题是,
v
为什么是一个整数变量,表达式
a2(B(v));
可以解析为函数声明…(这实际上是所问的问题)--从最后的评论中可以清楚地看出,用户已经知道这是一个最麻烦的解析,但想知道编译器是如何做到的。@DavidRodríguez dribeas你是对的,我添加了编译器是如何解释这一行的。哇,我没有意识到最麻烦的解析会变得如此糟糕。
int foo(int(bar)){返回0;}
为什么参数名称周围允许有括号?我原以为最麻烦的解析只有在初始值设定项可以被解析为函数类型时才会发生。现在我明白了,因为参数声明可以在参数名称周围有括号,这比这更糟糕。我想我很惊讶他们没有继续进行并进行“消歧”“注释”括号也适用于函数声明,因此我们无法消除歧义:
intfoo((int(bar)){return 0;}
显然,paren是允许的,因为它们在正常变量声明中是允许的:
intmain(){int(bar)=0;}
Why?@bames53与int(*f)中需要它们的方式相同()要声明函数指针,我认为在其他情况下需要统一允许它们。+1最后,一个答案解释了为什么可以将其解析为函数声明。
std::cout << a1.y.u << " " << a2.y.u << std::endl;
A<B> a2(B(v));
//is same as:
A<B> a2(B v);

//consider:
int foo(int v);
int foo(int (v));