【问题标题】:Why this is not a vexing parse?为什么这不是一个令人烦恼的解析?
【发布时间】:2011-05-08 08:08:11
【问题描述】:

基本上这是this question 对最令人烦恼的解析的跟进。我可以理解这是由于函数声明和变量定义之间的歧义。

但在Comeau online,我只是厌倦了以下。

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.
} 

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

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

【问题讨论】:

  • 为什么你会期望任何不同,你正确地构造了一个T的实例

标签: c++ most-vexing-parse


【解决方案1】:

因为10 不是类型。 :)

这将是一个最令人头疼的解析:

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

另一种最令人头疼的 Parse 是这个:

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      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

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

      请参阅the Wikipedia article

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-14
        • 2019-05-20
        相关资源
        最近更新 更多