在矢量上使用调整大小时,矢量内部结构中的unique_ptr不会编译
unique_ptr in structure inside vector doesn't compile when resize used on vector
VS2010
我有一个内部有unique_ptr
的结构。 然后我对这种结构有一个vector
。 如果我尝试调整矢量的大小(或使用保留),则会出现编译错误。 下面是一个精简的示例,它仍然表现出问题。
struct Test
{
unique_ptr<int> pValue;
};
void test()
{
// this doesn't compile
vector<Test> testVector;
testVector.resize(5);
// this also doesn't compile
testVector.reserve(5);
// this, of course, compiles
vector<unique_ptr<int>> testVector2;
testVector2.resize(5);
testVector2.reserve(5);
}
我得到的错误是关于访问unique_ptr
私有成员(分配运算符)的抱怨。 编译器正在尝试动态构造Test &Test::operator =(const Test &)
和Test::Test(const Test &)
。 我不明白为什么调整大小操作需要调用这些函数中的任何一个(如果需要,为什么它不直接调用默认构造函数? 它们都存在问题,因为由于const
,不可能用unique_ptr
制作任何一个。
我不想打断你和自己的谈话。
但答案是VS2010尚未完全实现C++11规范(这需要一些时间旅行)。 Test
应该有一个默认的 noexcept 移动构造函数,该构造函数调用unique_ptr
移动构造函数。 VS2010 不实现此隐式Test
移动构造函数。 如果是这样,您的完整示例将按预期编译和运行。 vector
将使用 noexcept 移动构造函数在需要时移动内容。
(另一种情况,写出并发布问题导致答案)
答案当然是unique_ptr<>
没有复制语义。 即便如此,我还是能够使用上述安排,直到我需要打电话给resize()
。 我没有想到的是,resize()
可能必须将块和其中的项目移动到另一个内存块。 这就是复制发生的时候。 尽管它只是非常临时的,但它仍然违反了复制过程中unique_ptr<>
的唯一性。
更让我困惑的是,由于unique_ptr<>
没有复制语义,vector<unique_ptr<>>
也不应该工作。 但答案必须是已经为这种情况编写了模板专用化。
我可能也可以为vector<Test>
编写一个模板专用化,以避免默认情况下向量类的延迟复制,从而避免上述编译器错误。 但是我对这个结构的使用不需要性能,所以让它使用shared_ptr<>
及其复制语义可以完成我需要的一切。