2017-10-07 75 views
2

C2280 - 試圖引用一個已刪除的功能是我收到錯誤時,我試圖從initializer_list構造一個std ::地圖>錯誤構建的std ::地圖<T,的unique_ptr <S>>從initializer_list

我做了一個最簡單的代碼(見下文)代表我的問題:

#include <string> 
#include <map> 
#include <memory> 
using namespace std; 

int main() { 
    map<string, unique_ptr<int>> MyMap{ 
     { "first" ,make_unique<int>(6) }, 
     { "second",make_unique<int>(22) }, 
     { "third" ,make_unique<int>(86) } 
    }; 
} 

所以我知道的unique_ptr無法複製,但由於make_unique將返回右值,應該不是的unique_ptr移動進入初始化器_List? 順便說一句,如果我用shared_ptr替換unique_ptr,那麼問題就解決了,但不是我正在尋找的解決方案,我想保留初始化樣式和unique_ptr。 那麼在這一點上,這個對已刪除函數的有問題的調用正在發生?有一種方法可以在不替換unique_ptr的情況下進行編譯?

+0

不幸的是,它並沒有真正那樣工作。你必須明確地[移動](http://en.cppreference.com/w/cpp/utility/move)指針。 –

+0

我已經將make_unique ()包含在move函數中,仍然不會編譯...我做錯了嗎?你能告訴我一個正確方法的例子嗎? –

+3

@Someprogrammerdude:這不是問題。指針正在正確地移入初始化器列表中。但他們沒有被移出初始化列表並進入地圖。我不認爲有這樣做的好方法。 –

回答

3

不幸的是,這是std::initializer_list對象的限制之一。他們只提供const訪問他們的元素,所以不可能移出他們的元素。你最好的選擇是以舊式的方式初始化你的地圖。

map<string, unique_ptr<int>> MyMap; 
MyMap["first"] = make_unique<int>(6); 
// etc. 

如果您需要的地圖是const,您可以創建一個臨時的地圖,並從移動:

const map<string, unique_ptr<int>> myMap = [] { 
    map<string, unique_ptr<int>> m; 
    m["first"] = make_unique<int>(6); 
    // etc. 
    return m; // RVO or implicit move 
}(); 

您還可以使用的std::map範圍內的構造,但你不得不爲自己寫一個特殊的迭代器類型,這會很煩人。

+1

您是否意味着在該lambda的末尾添加調用? –

+0

好吧,這很糟糕... xD然後,它是老式的時尚方式:) –

+0

@BenjaminLindley是的,謝謝你的發現。你也可以自己編輯答案:) – Brian

相關問題