2012-07-08 112 views
0

我試圖將unique_ptr的unordered_map移動到另一個映射中,但在下面得到編譯錯誤。將unique_ptr的unordered_map移動到另一個

#include <memory> 
#include <unordered_map> 
#include <string> 

int main() 
{ 
    std::unordered_map<int, std::unique_ptr<int>> aMap; 
    std::unordered_map<int, std::unique_ptr<int>> bMap; 

    std::unique_ptr<int> ptr(new int); 
    *ptr = 10; 
    aMap.insert(std::make_pair(0, std::move(ptr))); 

    std::move(aMap.begin(), aMap.end(), bMap.end()); 


    return 0; 
} 


1>------ Build started: Project: Testing, Configuration: Debug Win32 ------ 
1>Build started 08.07.2012 23:54:16. 
1>InitializeBuildStatus: 
1> Creating "Debug\Testing.unsuccessfulbuild" because "AlwaysCreate" was specified. 
1>ClCompile: 
1> main.cpp 
1>d:\progs\visual studio 2010\vc\include\utility(260): error C2166: l-value specifies const object 
1>   d:\progs\visual studio 2010\vc\include\utility(259) : while compiling  class template member function 'std::pair<_Ty1,_Ty2> &std::pair<_Ty1,_Ty2>::operator =(std::pair<_Ty1,_Ty2> &&)' 
1>   with 
1>   [ 
1>    _Ty1=const int, 
1>    _Ty2=std::unique_ptr<int> 
1>   ] 
1>   d:\coding\testing\main.cpp(12) : see reference to class template instantiation 'std::pair<_Ty1,_Ty2>' being compiled 
1>   with 
1>   [ 
1>    _Ty1=const int, 
1>    _Ty2=std::unique_ptr<int> 
1>   ] 
1> 
1>Build FAILED. 
1> 
1>Time Elapsed 00:00:00.64 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 
+2

我不認爲StackOverflow是有史以來最重要的東西,更不用說重新開始 – Fraser 2012-07-08 22:40:13

+0

我想我現在是延遲:) – bitgregor 2012-07-08 22:59:09

+0

我相信部分問題是插入和make_pair的組合正試圖調用複製唯一ptr的構造函數,它不存在。如果您將unique_ptr更改爲shared_ptr,它將會編譯到您的std :: move(aMap.begin()...也就是說,您在make_pair的爭論中對std :: move有正確的想法,就好像您一樣這是獨立的,但它工作,但失敗,並嘗試調用一個Map.insert上的複製構造函數。 – Trickfire 2012-07-08 23:08:15

回答

1

我認爲這是一個問題,你不能將元素添加到地圖或通過複製到最後設置。這說明這一個更簡單的例子是

std::set<int> aSet; 
std::set<int> bSet; 
aSet.insert(0); 

std::move(aSet.begin(), aSet.end(), bSet.end()); 

來解決這個問題,你需要一個insert_iterator,所以

std::move(aSet.begin(), aSet.end(), inserter(bSet, bSet.begin())); 

std::move(aMap.begin(), aMap.end(), inserter(bMap, bMap.begin())); 

內部,插入迭代器將嘗試呼叫'insert'在容器中傳遞,所以不是試圖做'*(bMap.end())= *(aMap.begin())',它會調用'bMap.insert(pos,*(aMap.begin ()))',儘管pos對於這種情況並不是非常重要灰。

+0

如果考慮到插入調用複製構造函數的問題,這意味着您將不得不使用shared_ptr's或找到不同的解決方案,此解決方案適用於此問題時可行。 – Trickfire 2012-07-08 23:15:13

+0

它感謝:) – bitgregor 2012-07-08 23:19:22

+0

@trickfire 是否需要插入調用複製構造函數?我真的沒有深入研究這個問題,但我會假設stl實現可能包含一個定義集 :: insert(T && rval)。即使您剛剛設置了傳值版本集 :: insert(T ppv),您仍可以防止複製;當'insert'被調用時,它被傳遞'T &&'(因爲它被std :: move調用)。當它遇到設置 :: insert(T ppv)時,它創建T ppv,並將作爲參數傳遞給std :: move的右值,因此T的移動構造函數被調用。與將值放置到集合中時相同。 – Rollie 2012-07-08 23:32:51

相關問題