【问题标题】:Unclear most vexing parse [duplicate]不清楚最令人头疼的解析[重复]
【发布时间】:2019-11-30 10:56:35
【问题描述】:

让我们假设以下类 Foo。

struct Foo
{
  int i;
};

如果我想创建这个类的一个实例并初始化它,我应该这样做:Foo foo1 = Foo(); 来调用构造函数。

int main(void)
{
    foo1 = Foo(); 
    cout << foo1.i << " : " << foo1.j << endl; // " 0 " 
}

然后我想我会用以下行调用默认构造函数,但它没有:

int main(void)
{
    Foo foo2(); // most vexing parse
    cout << foo2  << endl; // " 1 " ??? why?
    foo2.i++; // error: request for member ‘i’ in ‘foo2’, which is of non-class type ‘Foo()’ 
}

为什么 foo2 被初始化为 int(1) 而不是 Foo()?

我知道最令人头疼的 parse,它告诉我,根据我的理解,当一行可以被解释为一个函数时,它被解释为一个函数。

但是 foo1() 被解释为一个 int,不是一个函数,也不是一个 Foo 类。

Foo foo2() 行编译是因为它被解释为函数原型。好的。

为什么这行会编译? cout &lt;&lt; foo2 &lt;&lt; endl;

它会打印 foo2 函数的地址吗?

【问题讨论】:

  • 使用调试器找出编译器选择了哪个operator&lt;&lt;重载。
  • 如果我想创建这个类的一个实例并初始化它,我应该这样做:Foo foo1 = Foo(); 来调用构造函数。不,你应该这样做Foo foo1;Foo foo1 {};,这取决于你想做什么。
  • 请注意,这里没有“最麻烦的解析”。最令人头疼的解析确实涉及关于函数声明的相同规则。这是最令人头疼的解析示例:Foo foo2(int());(重写了我的评论,因为我原来的示例并不完整)

标签: c++ struct constructor default-constructor most-vexing-parse


【解决方案1】:

正如你所说,Foo foo2(); 是一个函数声明。对于cout &lt;&lt; foo2foo2 会衰减为函数指针,然后隐式转换为bool。作为非空函数指针,转换后的结果为true

不使用boolalphastd::basic_ostream&lt;CharT,Traits&gt;::operator&lt;&lt;output 1 用于true

如果 boolalpha == 0,则将 v 转换为 int 类型并执行整数输出。

使用std::boolalpha 可以看得更清楚。

cout << boolalpha << foo2  << endl;  // print out "true"

【讨论】:

    猜你喜欢
    • 2020-08-17
    • 2013-06-08
    • 1970-01-01
    • 2018-05-26
    • 2013-08-02
    • 1970-01-01
    • 2018-07-21
    • 1970-01-01
    相关资源
    最近更新 更多