2012-07-08 78 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

相关问题