2016-08-15 114 views
6

衆所周知,該標準C++ 11保證傳遞給函數的臨時對象將被之前的函數調用創建:Does standard C++11 guarantee that temporary object passed to a function will have been created before function call?標準C++ 11是否保證傳遞給函數的臨時對象在函數結束後會被銷燬?

但是,沒有標準的C++ 11保證傳遞給函數的臨時對象將有功能結束後(而不是之前)被銷燬?

工作草案,標準編程語言C++ 2016年7月12日:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf

§12.2的臨時對象

§12.2/5

有三個背景中的臨時的在完整表達式的結尾的 不同點處銷燬。第一個上下文 是調用缺省構造函數以初始化沒有相應初始化程序(8.6)的 數組的元素。第二個上下文是 ,當複製構造函數被調用來複制數組的一個元素時, 整個數組被複制(5.1.5,12.8)。在任何一種情況下,如果 構造函數具有一個或多個默認參數,則在構造下一個數組元素(如果有)之前,對在默認參數中創建的每個臨時文件的銷燬進行排序。當引用被綁定到臨時時,第三上下文是 。

另外:

§1.9/10

全表達是不是 另一表達子表達式的表達式。 [注意:在某些情況下,如未評估的 操作數,語法子表達式被認爲是全表達式 (第5章)。 - 結束註釋]如果語言結構被定義爲產生一個函數的隱式調用,則爲了該定義的目的,語言結構的使用被認爲是一個表達式。 A 調用除了臨時對象以外的對象 的生命週期結束時生成的析構函數是隱式的完整表達式。 爲了滿足 表達式 顯示的語言結構的要求,應用於表達式結果的轉換也被認爲是完整表達式的一部分。

這是否意味着標準C++ 11保證傳遞給函數的臨時對象在函數結束之前不會被破壞 - 而且恰好在完整表達式的結尾?

http://ideone.com/GbEPaK

#include <iostream> 
using namespace std; 

struct T { 
    T() { std::cout << "T created \n"; } 
    int val = 0; 
    ~T() { std::cout << "T destroyed \n"; } 
}; 

void function(T t_obj, T &&t, int &&val) { 
    std::cout << "func-start \n"; 
    std::cout << t_obj.val << ", " << t.val << ", " << val << std::endl; 
    std::cout << "func-end \n"; 
} 

int main() { 

    function(T(), T(), T().val); 

    return 0; 
} 

輸出:

T created 
T created 
T created 
func-start 
0, 0, 0 
func-end 
T destroyed 
T destroyed 
T destroyed 

,我們可以說,T destroyed永遠是func-end後?

而且這樣的:

function(T(), T(), T().val); 

總是等於這個:

{ 
    T tmp1; T tmp2; T tmp3; 
    function(tmp1, tmp2, tmp3.val); 
} 
+3

你的最後一部分以「這和:」開頭是不正確的,沒有。 (逗號運算符的左對齊不適用於函數參數。)期待這個好問題的正確答案。 – Bathsheba

+2

你不相信我的回答嗎? – NathanOliver

+0

@Bathsheba謝謝!錯字固定。 – Alex

回答

7

好,我們已經報所有,它告訴我們臨時的一生文本在年底結束全表達式。所以,是的,「T destroyed」將永遠持續。

如果破壞沒有觀察到的副作用的話,每AS-if規則,它可以實際上發生在之後的任何時間和hellip;但這是沒有意義的,因爲它不會被觀察到。

但是,您提交的最後兩個片段不是,通常是等價物,因爲您以某種不以前的方式修復了構建/初始化的順序。函數參數具有未指定的評估順序。不過,對於這個特殊的T,差別是不可觀察的。

+2

只是一個小小的修復:你可能會說「永遠會**最後**」。 –

+1

謝謝! 「被摧毀」總是會首先或最後(最後)?關於「臨時人的一生在完整表達式的結尾處結束」 - 但是在這種情況下,這是不是可觀察到的? http://ideone.com/DuY0GQ來自:https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Execute-Around_Pointer#Solution_and_Sample_Code – Alex

+0

@Yehezkel:哈哈是啊oops obvs –

相關問題