最烦人的解析C++11

Most vexing parse C++11

本文关键字:C++11      更新时间:2023-10-16

我对这条线到底Y y {X{}};做什么以及它与最令人烦恼的解析有什么联系感到困惑。欢迎简要说明:

#include <iostream>
struct X {
    X() { std::cout << "X"; }
};
struct Y {
    Y(const X &x) { std::cout << "Y"; }
    void f() { std::cout << "f"; }
};
int main() {
    Y y { X{} };
    y.f();
}

这条线到底有什么作用

它创建一个临时X,通过调用默认构造函数对其进行值初始化,然后使用它来初始化Y变量,调用const X&转换构造函数。

与最烦人的解析的连接在哪里

如果你尝试使用老式的初始化语法来编写它

Y y (X());

然后所谓的"最烦人的解析"会将其解释为一个函数,而不是一个变量,声明:一个名为 y 的函数,返回类型为 Y 和单个参数,其类型是返回 X 的(指针指向 a)函数。

您可以添加额外的括号,以便它不能被解释为函数声明:

Y y ((X()));

或者,从 C++11 开始,您可以像示例一样使用大括号初始化。

Y y { X{} };

这是完美的,y将类型X的临时对象传递给构造函数来创建一个对象。没有令人烦恼的解析(大多数或其他)。实际上,引入使用 {} 的构造是为了解决在许多情况下令人烦恼的解析问题,例如:

 Y y1();
 Y y2(X());
两者都

属于(大多数)令人烦恼的解析,因此两者都声明函数而不是对象。

但是,如果使用称为大括号初始化的大括号

 Y y1{};
 Y y2{ X{} }; //as you've done yourself

然后,两者都按预期声明对象,而不是函数。