繁体   English   中英

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

[英]Does returning a temporary object create a temporary object in C++?

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

struct A {A(int);};
A foo() {return static_cast<A>(0);}
A x = foo();

这里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语句会再次创建一个临时对象吗?

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

(§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";
    }
};

临时对象(最有可能)将通过返回值优化 (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;
}

输出: 实例

A

禁用RVO的输出: 实例

A
A&&
A&&

简短回答:不会在代码中只创建A

为此,编译器使用(Named)返回值优化 ,在返回时消除不必要的对象创建/复制。 更一般的情况, 复制省略,消除不必要的对象复制,将在大量相关的情况下使用。

您可以使用GCC选项-fno-elide-constructors来查看差异。

在这种特定情况下的实际结果将取决于特定的编译器和优化级别。 实际上,具有良好优化级别的现代编译器可以完全删除任何临时对象。 考虑一下:

#include <iostream>

using namespace std;

struct A {
    A(int) { cout << __PRETTY_FUNCTION__ << endl; }
    ~A() { cout << __PRETTY_FUNCTION__ << endl; }
};

inline
A foo() {
    return static_cast<A>(0);
};


int main(void) {
    A a = foo();
    cout << "hello world!" << endl;
}

带-O4的gcc-5.1.1构建一个可执行文件,输出字面意思:

A::A(int)
hello world!
A::~A()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM