[英]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.