VS2010
我的结构里面有unique_ptr
。然后我有vector
这个结构。如果我尝试调整向量(或使用reserve),我会收到编译错误。下面是一个精简的例子,仍然存在问题。
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 &)
。我不明白为什么调整大小操作需要调用这些函数中的任何一个(为什么不调用默认构造函数,如果它需要?)。它们都存在问题,因为由于unique_ptr
而无法使用const
。
答案 0 :(得分:6)
我讨厌打断你与自己的对话。 : - )
但答案是VS2010尚未完全实现C ++ 11规范(这需要一些时间旅行)。 Test
应该有一个默认的noexcept移动构造函数,它可以调用unique_ptr
移动构造函数。 VS2010没有实现这个隐式Test
移动构造函数。如果是这样,您的完整示例将按预期编译并运行。 vector
将使用noexcept移动构造函数在需要时移动它。
答案 1 :(得分:0)
(写出并发布问题的另一个案例导致答案)
答案当然是unique_ptr<>
没有复制语义。即便如此,我还是可以使用上述安排,直到我需要拨打resize()
。我没有想到的是resize()
可能必须将块和项目移动到另一个内存块。那就是复制发生的时候。尽管它只是非常短暂的,但在复制过程中仍然会违反unique_ptr<>
的唯一性。
让我感到困惑的是,由于unique_ptr<>
没有复制语义,vector<unique_ptr<>>
也不应该有效。但答案必须是为此案例编写了模板专业化。
我可能也会为vector<Test>
编写一个模板专门化,以避免默认情况下向量类的延迟复制,从而避免上述编译器错误。但是我对这个结构的使用并不需要性能,所以相反使它使用shared_ptr<>
及其复制语义来完成我需要的一切。