C++11 使用std::make\u move\u迭代器插入std::list时出错<;标准::唯一性\u ptr>&燃气轮机;换成另一个
我一直在阅读有关使用C++11 使用std::make\u move\u迭代器插入std::list时出错<;标准::唯一性\u ptr>&燃气轮机;换成另一个,c++11,linked-list,insert,move-semantics,unique-ptr,C++11,Linked List,Insert,Move Semantics,Unique Ptr,我一直在阅读有关使用std::make\u move\u迭代器将元素从std::vector移动到另一个元素的内容。它可以完美地工作: std::vector<std::unique_ptr<int>> c1; std::vector<std::unique_ptr<int>> c2; c1.push_back(std::unique_ptr<int>(new int)); c2.insert(c2.end(), std::make_m
std::make\u move\u迭代器将元素从std::vector
移动到另一个元素的内容。它可以完美地工作:
std::vector<std::unique_ptr<int>> c1;
std::vector<std::unique_ptr<int>> c2;
c1.push_back(std::unique_ptr<int>(new int));
c2.insert(c2.end(), std::make_move_iterator(c1.begin()), std::make_move_iterator(c1.end()));
但编译失败的原因是:
错误C2248:“std::unique\u ptr::unique\u ptr”:无法访问在类“std::unique\u ptr”中声明的私有成员
但是,如果列表包含其他对象(如std::string
),则它确实有效:
据我所知,此解决方案基本上在向后插入第二个容器时分别移动每个项目
我的问题是,为什么在std::unique\u ptr
的std::list
上使用std::make\u move\u迭代器不起作用,但它与std::vector
一起使用,或者如果列表元素是不同类型的
注意:我使用的是Visual Studio 2010。核心问题是Visual Studio 2010对std::list::insert
的实现不支持移动语义。在内部,std::list::insert
调用一个名为\u insert
的方法,该方法在VS 2010中声明如下:
void _Insert(const_iterator _Where, const _Ty& _Val)
在VS 2017中(未检查其他版本),它调用相同的方法,但声明为:
void _Insert(_Unchecked_const_iterator _Where, _Valty&&... _Val)
如图所示,VS 2017使用右值引用,因此在进行插入时调用std::unique_ptr
的移动构造函数。另一方面,VS 2010使用左值引用,因此在某个时刻调用复制构造函数,该构造函数被声明为私有的std::unique_ptr
,生成编译错误
结论
在VS 2010中,无法使用基于std::make\u move\u iterator
的解决方案,因为std::list::insert
是如何实现的。将std::list
附加到另一个列表中的选项包括:
- 使用:
- 使用(credit to),这非常有用,因为它可以直接用于函数返回的列表:
c2.splice(c2.end(), c1);
VS2010很古老。与VS2017。有趣的。。。谢谢我想知道它是否有解决办法?如问题中所述,我有另一个解决方案,但我暂时无法从VS 2010迁移。对于在列表之间移动,您可能应该使用splice
。很好的建议,谢谢!正如你所说,它实际上是更直接和自我记录的
void _Insert(const_iterator _Where, const _Ty& _Val)
void _Insert(_Unchecked_const_iterator _Where, _Valty&&... _Val)
std::move(c1.begin(), c1.end(), std::back_inserter(c2));
c2.splice(c2.end(), c1);