2016-02-23 48 views
1

行我有事件序列:在返回之前是否會破壞參數?

  1. 我構造的r值對象
  2. 我通過一個迭代到r值對象到一個函數作爲參數
  3. 功能在此操作迭代器
  4. 該函數返回該迭代器值
  5. 我取迭代

我不知道是什麼原因導致了r值對象的清理,是否終止了該行?

好了,現在具體情況,我試圖想出了這個問題一個更好的答案:string Multiplication in C++和我有代碼:

const auto bar = 13U; 
const char multiplicand[] = "0, "; 
const auto length = strlen(multiplicand); 
const string foo(&*generate_n(string(bar * length, '\0').begin(), bar * length, [&]() { 
    static auto i = 0U; 
    return multiplicand[i++ % length]; 
}) - bar * length); 

所以我想知道這是建造時string裏面的generate_n應該被銷燬。順便說一句,這似乎在gcc 5.1上工作正常:但我可能會得到未定義的行爲。這是由以下事實:Visual Studio中的代碼段錯誤2015

+1

不是[this](http://stackoverflow.com/questions/2506793/c-life-span-of-temporary-arguments)回答這個關於一生的問題嗎? – NathanOliver

+0

@NathanOliver它的確如此說:「通常這意味着它結束於';'(或')''''''''if','while','switch'等)表示語句結束。在你的例子中,這是函數調用的結束。「我認爲'''是我的問題的答案。但是,聲明中的「通常」並不是確定性的。如果清理應該推遲到''''那麼我是金,但這將意味着微軟做錯了...... –

+1

我不知道這段代碼是否調用UB,但是對它的任何更好的答案不。 –

回答

1

臨時變量如string(bar * length, '\0')滿表達式的結尾被破壞暗示。完整表達式是const string foo的初始值設定項。因此,臨時字符串在foo的返回之前不會被銷燬。

+0

這就是我從閱讀第12.2節的想法。但是,我們的意見不足以支持這個答案。你能給一個源頭嗎? –

+0

來源確實是12.2。注意這個明顯的異常並不適用:「有兩種上下文在臨時表被銷燬在不同於完整表達式結尾的地方,第一個上下文是當表達式作爲初始化符出現時,一個對象,在這種情況下,保留表達式結果的臨時對象應該一直保持到對象初始化完成「。這不適用,因爲它僅適用於臨時表達式,而不適用於任何其他臨時表達式。 – MSalters

+0

好的,我同意,但那是暫時性的*返回*。 12.2 [class.temporary] 2說了表達式'X b = f(X(2));':「一個實現可能會使用一個臨時的構造'X(2)',然後傳遞給'f() ''使用''X'的拷貝構造函數;或者'X(2)'可能在用於保存參數的空間中構造。「我的問題是,如果參數不通過值,那麼用於保存參數的臨時/空間何時被清除? –