10

考虑以下程序:

#include <fstream>

struct A {};

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

C++1y 模式中的 Clang 认为 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]));

        ^

        (                    )

我了解MVP,但在这种情况下不是:argv[1]显然是一个表达式,并且在它之前没有类型,那么如何将这一行解析为函数声明?

argv[1]是不是在编译器已经选择将行解析为函数声明之后才会发生语义解释,这将消除该行作为对象声明的歧义?或者它是一个 Clang 错误?还是通过对argv [ 1 ]我缺少的令牌的一些解释完全正常?

4

2 回答 2

13

我认为它被解析为

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

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

当然,实际上,该数组参数衰减为一个指针,所以你最终在语义上是:

A a(std::fstream* argv);
于 2014-02-07T10:14:01.307 回答
3

括号是多余的。以下都是声明:

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

希望有帮助。

于 2014-02-07T10:16:49.743 回答