返回临时对象是否在C++中创建临时对象?

xsk*_*xzr 10 c++ return type-conversion temporary-objects

考虑C++中的以下代码:

struct A {A(int);};
A foo() {return static_cast<A>(0);}
A x = foo();
Run Code Online (Sandbox Code Playgroud)

这里static_cast<A>(0)通过标准[5.2.9-4]创建一个临时对象,它是一个prvalue.标准[12.2-1]说

类型的临时数在各种上下文中创建:绑定对prvalue的引用(8.5.3),返回prvalue(6.6.3),创建prvalue的转换(4.1,5.2.9,5.2.11,5.4) ,抛出异常(15.1),进入处理程序(15.3),以及一些初始化(8.5).

那么return语句会再次创建一个临时对象吗?

顺便说一下,任何人都可以告诉我标准是否保证隐式类型转换会创建一个临时对象?

Sin*_*all 7

(§4/ 6)提到了这一点

任何隐式转换的效果与执行相应的声明和初始化相同,然后使用临时变量作为转换的结果.

所以是的,除非经过优化,否则应该创建一个临时的,但我确信所有现代编译器都会在您的情况下执行复制省略.此特定优化称为返回值优化(RVO).您可以通过具有副作用的构造函数来轻松地测试它:

struct A {
    A(int){
        std::cout << "ctor";
    }
    A(const A & other)
    {
        std::cout << "copy ctor";
    }
    A(A&&other)
    {
        std::cout << "move ctor";
    }
};
Run Code Online (Sandbox Code Playgroud)


m.s*_*.s. 5

临时对象(最有可能)将通过返回值优化(RVO)进行优化.

例:

#include <iostream>
struct A
{
    A(int)
    {
        std::cout<< "A" << std::endl;
    }
    A(const A&)
    {
        std::cout << "A&" << std::endl;
    }
    A(A&&)
    {
        std::cout << "A&&" << std::endl;
    }
};
A foo() {return static_cast<A>(0);}

int main()
{
    A x = foo();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:实例

A
Run Code Online (Sandbox Code Playgroud)

禁用RVO的输出:实例

A
A&&
A&&
Run Code Online (Sandbox Code Playgroud)