2012-04-13 43 views
3

VS2010的unique_ptr在內部向量結構當矢量

用於調整大小我有具有unique_ptr內的結構不編譯。然後我有這個結構的vector。如果我嘗試調整矢量大小(或使用保留),則會出現編譯錯誤。下面是一個精簡的例子,它仍然存在這個問題。

struct Test 
{ 
    unique_ptr<int> pValue; 
}; 

void test() 
{ 
    // this doesn't compile 
    vector<Test> testVector; 
    testVector.resize(5); 

    // this also doesn't compile 
    testVector.reserve(5); 

    // this, of course, compiles 
    vector<unique_ptr<int>> testVector2; 
    testVector2.resize(5); 
    testVector2.reserve(5); 
} 

我得到的錯誤是關於訪問的unique_ptr(賦值運算符)的私有成員的投訴。編譯器試圖動態構造Test &Test::operator =(const Test &)Test::Test(const Test &)。我不明白爲什麼調整大小的操作需要調用這些函數(爲什麼它只是在需要時調用默認構造函數?)。他們都提出了問題,因爲由於const而導致無法使用unique_ptr

回答

6

我討厭打斷你與你的談話。 :-)

但答案是,VS2010還沒有完全實現C++ 11規範(這將需要一點時間旅行)。 Test應該有一個默認的noexcept移動構造函數,它調用unique_ptr移動構造函數。 VS2010沒有實現這個隱式的Test移動構造函數。如果是這樣,您的完整示例將按預期進行編譯和運行。 vector將使用noexcept移動構造函數來移動需要的東西。

+0

我很欣賞中斷! :-)我從來不會猜測問題是V10(現在是VC11)不執行'noexcept'。 http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx – dsmtoday 2012-04-15 04:12:13

0

答案(其中寫出,並張貼導致答案的問題另一種情況),當然,是​​沒有拷貝語義。即使如此,我仍然可以使用上述安排,直到我需要撥打resize()。我沒有想到的是,resize()可能需要將塊和項目移動到另一個內存塊。那是複製發生的時候。儘管它只是非常臨時的,但它在複製過程中仍然違反​​的唯一性。

讓我更困惑的是,由於​​沒有複製語義,因此vector<unique_ptr<>>也不應該有效。但答案必須是爲這種情況編寫模板專業化。

我大概可以寫一個vector<Test>的模板專門化,以避免默認情況下,延遲複製矢量類,從而避免上述編譯器錯誤。但是我使用這個結構並不需要性能,所以使用shared_ptr<>和它的複製語義來完成我所需要的一切。