为什么这不是一个令人烦恼的解析

Why this is not a vexing parse?

本文关键字:烦恼 一个 这不是 为什么      更新时间:2023-10-16

基本上,这是关于最烦人的解析问题的后续。我可以理解这是由于函数声明和变量定义之间的歧义。

但是在科莫在线,我只是厌倦了以下内容。

class T{
public:
    T(int i){
    }
    int fun1(){
        return 1;
    }
};
int main()
{
    T myT(10); // I thought it'd be a function declaration that takes an int and returns a type T
    myT.fun1(); // and a compiler error out here.
} 

但它编译得很好,没有错误。我查看了标准文档,但无法得出推理。

那么,我在这里错过了什么?

因为10不是一种类型。 :)

这将是一个最令人烦恼的解析:

T myT(T());
// T() gets interpreted as function pointer argument to a function returning T();
// This is equivalent to:
T myT(T (*fn)());

最令人烦恼的解析的另一个变体是这个:

unsigned char c = 42;
T myT(int(c));
// int(c) gets interpreted as an int argument called c.
// This is equivalent to:
T myT(int c);

10不能是参数类型名称,因此这必须是变量声明。

编译器必须选择函数声明,当它可以这样做时,但在许多情况下,它不能并且没有歧义。

这不是

一个令人烦恼的解析,因为你使用了整数文字,而不是说:

T myT(T());

如这个完整示例所示:

#include <iostream>
struct T { int f() { return 1; } };
int main(int argc, char** argv) {
    T t(T());
    std::cout << t.f() << 'n';
    return 0;
}

这是模棱两可的,因为它可能意味着:

  • myT是用默认构造的T初始化的T;或
  • myT是一个返回T并接受一个类型为 T() 的参数的函数,它表示返回类型也是 T 的零参数函数。

后一种解释是默认的解释,这就是为什么尝试使用新声明的函数会导致编译器错误的原因,就好像它是您期望的对象一样。

请参阅有关它的维基百科文章。