Ale*_*ter 2 c++ compiler-optimization c++11
我正在尝试学习 C++ 中的资源管理,在我的研究中我遇到了一个有趣的优化。基本上,当使用复制构造函数初始化堆栈上的对象时,该对象是一个右值对象(它是右值对象吗?),而不是调用构造函数然后调用移动构造函数,编译器只是调用原始对象的构造函数。
Object c(Object(1)); // This is the same as Object c(1);
Object c(Object(Object(Object(Object(Object(1)))))); // This is also the same as Object c(1);
Run Code Online (Sandbox Code Playgroud)
Expected flow:
1. Object(1) calls the constructor and creates a nameless Object that will be removed as soon as it's created.
2. c notices this is an rvalue, and calls the move constructor.
3. Destructor for Object(1) is called.
Run Code Online (Sandbox Code Playgroud)
Actual flow:
1. c(1) is called.
Run Code Online (Sandbox Code Playgroud)
这很聪明,但是..如何?这个技巧背后的机制是什么?即使 Object 的构造函数接受指针和许多参数,这也有效。
在 C++17 之前,此行为属于复制省略。Object(x)指定创建临时对象,但编译器可以自行决定在某些情况下省略创建和销毁所有临时对象。
由于 C++17这改变了,现在Object(x)意味着迟早会有一个Objectcreated with initializer x。该对象称为结果对象,结果对象的身份由此表达式出现的上下文确定,在您的代码中c是该形式的所有表达式的结果对象,并且两行完全相同Object c(1);。这适用于类别prvalue 的所有表达式。
后者为编码人员提供了更多的确定性,即不会制作不必要的副本。