这个声明如何引用最令人烦恼的解析?

时间:2014-02-07 10:12:38

标签: c++ most-vexing-parse

考虑以下计划:

#include <fstream>

struct A {};

int main(int argc, char** argv) {
    A a(std::fstream(argv[1]));
}

Clang in C ++ 1y模式估计调用了MVP,a is parsed as a function declaration

clang++ -std=c++1y -O3 -Wall -Wextra -pedantic-errors -pthread main.cpp && ./a.out

main.cpp:6:8: warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]

    A a(std::fstream(argv[1]));

       ^~~~~~~~~~~~~~~~~~~~~~~

main.cpp:6:9: note: add a pair of parentheses to declare a variable

    A a(std::fstream(argv[1]));

        ^

        (                    )

我理解MVP,但不是在这个例子中:argv[1]显然是一个表达式,并且之前没有类型,所以如何将这一行解析为函数声明?

argv[1]上的语义解释是否会将该行作为对象声明消除歧义,直到编译器已经选择将该行解析为函数声明之后才会出现?或者它是一个Clang bug?或者通过对我遗忘的令牌argv [ 1 ]的一些解释是完全正常的吗?

2 个答案:

答案 0 :(得分:13)

我认为它被解析为

A a(std::fstream argv[1]);

即。一个接收1 std::fstream数组的函数,其中额外的括号是多余的。

当然,实际上,该数组参数会衰减为指针,因此您最终使用语义

A a(std::fstream* argv);

答案 1 :(得分:3)

parens是多余的。以下所有都是声明:

T a;
T (a);
T ((a));
T (((a))));

这些也是:

T a[1];
T (a[1]);
T ((a[1]));
T (((a[1]))));

这就是:

 A a(std::fstream(argv[1]));

与:

相同
 A a(std::fstream argv[1]);

与:

相同
 A a(std::fstream *argv);

希望有所帮助。