2014-09-30 60 views
5

雖然使用C#工作了好幾年,但用C++完成工作對我而言仍然有些困難。我完全接受智能指針的使用,但現在我正面臨以下難題:我有一個struct Foo,例如,使用包含std :: unique_ptr的std :: vector構造一個類時出現錯誤

struct Foo 
{ 
    Foo(std::unique_ptr<Bar> bar) : m_myBar(std::move(bar)) {} 

private: 
    std::unique_ptr<Bar> m_myBar;   
}; 

在不同的類,我想有一個包含美孚的實例的載體,但是下面一行

std::vector<Foo> m_Foos; 

產量編譯錯誤說,拷貝構造函數被刪除。在SO線程「Why can I not push_back a unique_ptr into a vector?」中給出瞭解釋和補救措施。然而,問題涉及到唯一指針的向量,而我有一個包含唯一指針的結構向量。建議的解決方案是使用移動語義,但如何適用於我的情況?或者我應該做其他事情?

+0

您是否使用Visual Studio? – Angew 2014-09-30 07:54:31

+0

不,我使用基於Qt 5.3.1的Qt Creator 3.1.2和mingw32-make.exe。這很重要嗎? – SimonAx 2014-09-30 07:55:57

+0

哪個編譯器?我認爲mingw gcc,這應該是好的。 Visual Studio的編譯器不能自動生成移動窗口。但矢量線本身不會導致錯誤,請參閱我的答案中的鏈接。它可能是封閉在一個班,這會影響該班的副本嗎? IOW,請發佈[MCVE](http://stackoverflow.com/help/mcve)。 – Angew 2014-09-30 08:09:48

回答

4

正如你所說,m_Foos實際上是另一個類的數據成員(我稱之爲FooHolder)。如果您沒有提供FooHolder的複製構造函數,編譯器將自動生成一個。該複製構造函數將調用FooHolder的所有數據成員的複製構造函數,其中包括m_Foos。當然,std::vector<Foo>的拷貝構造函數包含編譯錯誤,因爲Foo不可複製。這可能是你得到錯誤的原因。

如果您能夠並且希望該類可複製,則必須爲FooHolder提供適當的複製構造函數。否則,你可以聲明一個移動構造函數(可能是默認的),這將使複製構造函數被刪除:

struct FooHolder 
{ 
    FooHolder(FooHolder&&) = default; 

private: 
    std::vector<Foo> m_Foos; 
}; 
+0

由於'Foo'不是可複製構造的,因此嘗試將'Foo'的'push_back'左值時可能仍然存在錯誤,這值得提及 – 2014-09-30 08:06:24

+0

@PiotrS。 OP聲稱錯誤來自矢量的定義 - 它沒有。答案也是移動結構本身。 – Angew 2014-09-30 08:07:38

+0

閱讀Kerrek的回答 – 2014-09-30 08:09:30

1

您不能複製唯一的指針。您只能移動他們:

Foo(std::unique_ptr<Bar> bar) : m_myBar(std::move(bar)) {} 
//          ^^^^^^^^^^^^^^ 
+0

@angew和Kerrek。感謝您指出我無法輸入:-s在我原來的問題中,我忘記了包括我使用std :: move,這兩個都提到了。我已經更新了我的原始問題以反映這一點。當刪除行std :: vector m_Foos時,程序編譯,我甚至可以構造Foo對象,所以我非常確定該向量導致了問題。 – SimonAx 2014-09-30 08:07:14

+0

@SimonAx:你在矢量上執行了哪些操作?你是否試圖用'std :: vector'複製另一個類? – 2014-09-30 08:09:08

+0

@PiotrS。我還沒有對矢量執行任何操作。在進一步推回元素之前,我想驗證程序是否已編譯,但沒有。 – SimonAx 2014-09-30 08:11:51

相關問題