2013-06-06 34 views
3

我正在使用emplace_back將項目添加到std::deque。在施工期間,新物品可能會將其他物品添加到正在構建的std::deque中。這導致非常有趣的行爲。考慮這個片斷:在調用emplace_back期間修改std :: deque是否合法?

#include <iostream> 
#include <deque> 
#include <string> 

struct foo 
{ 
    std::string m_marker; 

    foo(std::deque<foo>& into, const std::string& marker, bool createInner = true) 
    : m_marker(marker) 
    { 
     if (createInner) 
     { 
      std::cout << "Marker is " << m_marker << std::endl; 
      into.emplace_back(into, "my other marker", false); 
      std::cout << "Marker is now " << m_marker << std::endl; 
     } 
    } 
}; 

int main() 
{ 
    std::deque<foo> foos; 
    foos.emplace_back(foos, "my initial marker"); 

    std::cout << "There are " << foos.size() << " items in the deque:" << std::endl; 
    for (foo& f : foos) 
    { 
     std::cout << f.m_marker << std::endl; 
    } 
} 

它創建foodeque對象。第一個對象的標記是"my initial marker",並且由於createInnertrue,它將創建第二個對象。我希望以下結果:

Marker is my initial marker 
Marker is now my initial marker 
There are 2 items in the deque: 
my initial marker 
my other marker 

然而,隨着鏗鏘++(標籤/蘋果/鐺-421.11.66))和libc(++(不知道它是什麼版本),這是我得到:

Marker is my initial marker 
Marker is now my other marker 
There are 2 items in the deque: 
my other marker 
  

正如您所看到的,第一個對象的m_marker字段被第二個對象覆蓋,而第二個顯示在雙側的對象現在是空的。所以很明顯,某處存在一個錯誤,它必須是在調用emplace_back期間修改deque的未定義行爲,或者libC++沒有完成其工作。哪一個?

+0

_why_你會那麼做嗎?! – stefan

+0

您可能感興趣的相關問題:http://stackoverflow.com/questions/16616253/is-vectorinsert-allowed-to-reserve-only-once-and-avoid-further-capacity-checks –

+1

我會說這是未定義的行爲。該標準僅爲函數運行前後提供了保證。 –

回答

2

,霍華德Hinnant(欣南特)回答on the bug report,標準不說的這種情況下任何東西,但它需要說,它會導致不確定的行爲:因爲異常安全的考慮

在每種情況下,該 集裝箱是不「改變」,直到完成一個foo的構造是 。這樣,如果foo構造函數拋出,容器 狀態不變。例如,直到 foo構造函數完成後,vector.size()纔會被更改。因此,當第一個 構造在第一個構建完成之前開始時,它仍然會附加到零長度向量上,即 。

這不是一個可以在容器的執行 中解決的問題。標準需要說「不要那樣做」。

所以不要指望它與任何實現一起工作。