对持有unique_ptr类型vector的对象列表进行排序
Sorting a list of objects holding a vector of unique_ptr
下面的代码应该根据c++ 11产生编译错误(如果是为什么?)或者它是VC11的问题?
#include <vector>
#include <list>
#include <memory>
struct A
{
std::vector<std::unique_ptr<int>> v;
};
int main()
{
std::list<A> l;
l.sort([](const A& a1, const A& a2){ return true; });
}
Visual c++ 2012产生以下编译错误:
1>c:program files (x86)microsoft visual studio 11.0vcincludexmemory0(606): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
1> with
1> [
1> _Ty=int
1> ]
1> c:program files (x86)microsoft visual studio 11.0vcincludememory(1447) : see declaration of 'std::unique_ptr<_Ty>::unique_ptr'
1> with
1> [
1> _Ty=int
1> ]
1> c:program files (x86)microsoft visual studio 11.0vcincludexmemory0(605) : while compiling class template member function 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)'
1> with
1> [
1> _Ty=std::unique_ptr<int>
1> ]
1> c:program files (x86)microsoft visual studio 11.0vcincludexmemory0(751) : see reference to function template instantiation 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<int>
1> ]
1> c:program files (x86)microsoft visual studio 11.0vcincludetype_traits(743) : see reference to class template instantiation 'std::allocator<_Ty>' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<int>
1> ]
1> c:program files (x86)microsoft visual studio 11.0vcincludevector(655) : see reference to class template instantiation 'std::is_empty<_Ty>' being compiled
1> with
1> [
1> _Ty=std::allocator<std::unique_ptr<int>>
1> ]
1> d:test2test2.cpp(213) : see reference to class template instantiation 'std::vector<_Ty>' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<int>
1> ]
这是" VC的问题",但只是因为你滥用了Visual Studio。
vc++实现了r值引用,但是没有实现编译器生成的移动构造函数/赋值操作符。这意味着,如果你想让一个类型是可移动的,你必须自己写一个。
A
不是可移动类型,因此各种std::list
函数将尝试复制它们。当他们试图复制vector
或unique_ptr
时,他们会失败。因此会出现编译错误。
如果你想在vc++中使用移动感知对象,你必须自己为它们编写移动构造函数/赋值。
这个问题实际上是在VC11中,因为它没有实现c++ 11的自动生成移动操作的功能(已经被nicolbolas确定)。
下面的代码在VC10 SP1下编译;在这个代码示例中,move构造函数是显式地编写的(对于move operator=
,使用复制和交换习惯)。
#include <algorithm> // for std::swap (for copy-and-swap idiom)
#include <list>
#include <memory>
#include <vector>
struct A
{
std::vector<std::unique_ptr<int>> v;
A(A&& other)
: v( std::move(other.v) )
{
}
A& operator=(A other)
{
swap(*this, other);
return *this;
}
friend void swap(A& lhs, A& rhs)
{
using std::swap;
swap(lhs.v, rhs.v);
}
};
int main()
{
std::list<A> l;
l.sort( []( const A& , const A& ){ return true; } );
}
这是Visual c++ 2012的一个问题(由Microsoft在Connect上承认:c++代码中的编译错误排序持有unique_ptr向量的对象列表),它已经在Visual c++ 2013中修复了。
另外,我想指出一个问题与visualc++不隐式地生成move构造函数这一事实无关。如果在我的原始示例中显式删除结构A中的所有复制和移动构造函数(是的,它将使不可能将A类型的对象插入到列表中,但这不是重点),代码仍然不应该复制或移动任何对象,因此会产生编译错误:
#include <vector>
#include <list>
#include <memory>
struct A
{
std::vector<std::unique_ptr<int>> v;
A(A&&) = delete;
A(const A&) = delete;
};
int main()
{
std::list<A> l;
l.sort([](const A& a1, const A& a2){ return true; });
}
相关文章:
- 我使用向量来创建类对象列表.初始化向量时如何使用参数调用构造函数?
- 如何在不销毁对象的情况下返回对象列表
- 如何使用Q_PROPERTY公开自定义对象列表
- 什么更好?返回对象指针列表?或返回指向对象列表的指针?
- c++ 循环访问对象列表并删除对象
- 循环访问对象列表 c++
- Cython正在获取C++对象列表的长度
- 如何在屏幕上显示对象列表?
- Strcmp 类行为应用于C++中的对象列表
- 如何迭代指针指向的对象列表?
- C++对象列表数组
- 使用BOOST :: PYTHON返回裸露的类对象列表,这些对象是不可复制的
- 返回对象列表
- C 链接对象列表
- 使用for_each从对象列表中调用打印功能
- 从对象列表中获取具有特定成员值的所有对象
- 按指针列出的 C++ 对象列表
- 子类对象列表重新解释为基类对象列表?(C++11).
- 在C++中的混合对象列表中使用相同的方法
- Python:我们应该如何编写一个函数来返回对象/列表和布尔标志