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

Lig*_*ica 9 c++ most-vexing-parse

考虑以下程序:

#include <fstream>

struct A {};

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

Clang in C++ 1y模式估计MVP被调用,因此a被解析为函数声明:

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]));

        ^

        (                    )
Run Code Online (Sandbox Code Playgroud)

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

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

Meh*_*dad 13

我认为它被解析为

A a(std::fstream argv[1]);
Run Code Online (Sandbox Code Playgroud)

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

当然,实际上,该数组参数会衰减为指针,因此您最终的语义结果是:

A a(std::fstream* argv);
Run Code Online (Sandbox Code Playgroud)

  • @Nawaz:_"`[C++ 11:8.3.5/5]:`在确定每个参数的类型后,任何类型为"T的数组"或"返回T的函数"的参数都被调整为"指向T"或"指向函数返回T的指针."_这意味着参数以`T [N]`开头,变为`T*`,之后参数当然只能取类型`T*`因为这就是参数类型的变化. (4认同)
  • @Nawaz:一个参数可以是一个数组(它只是一个占位符,你可以这样声明它,没问题),但参数不能(因为参数是一个值,值传递,但数组可以'传递). (3认同)
  • @Nawaz:不,我的答案正是我告诉你的,以及标准所说的.这是与你无关紧要的辩论,因为你正在与标准辩论,所以我现在就停止. (3认同)
  • 啊,是的,就是这样.我_always_想念这个案子!谢谢 :) (2认同)
  • -1.这部分是错误的>>`一个接收1 std :: fstream`数组的函数.参数不是数组,它是一个指针! (2认同)