避免使用向量向量进行复制

时间:2009-12-11 18:37:40

标签: c++ optimization memory-management stl vector

我希望能够拥有某种类型的矢量矢量,例如:

vector<vector<MyStruct> > vecOfVec;

然后我创建一个MyStruct矢量,并填充它。

vector<MyStruct> someStructs;
// Populate it with data

然后最后将someStructs添加到vecOfVec;

vecOfVec.push_back(someStructs);

我想要做的是在推送向量时避免使用复制构造函数调用。我知道这可以通过使用指针向量来实现,但如果可能的话我想避免这种情况。

我想到的一个策略似乎有效,但我不知道我是否过度设计了这个问题。

// Push back an empty vector
vecOfVec.push_back(vector<MyStruct>());

// Swap the empty with the filled vector (constant time)
vecOfVec.back().swap(someStructs);

这似乎会添加我的矢量而不必做任何副本,但这似乎是编译器在优化过程中已经做的事情。

你认为这是一个好策略吗?

编辑:由于一些建议而简化了我的交换声明。

5 个答案:

答案 0 :(得分:6)

交换技巧与C ++ 03一样好。在C ++ 0x中,您将能够通过std::move使用向量的移动构造函数以更明显的方式实现相同的功能。

另一种选择是不创建单独的vector<MyStruct>,而是让创建它的代码接受一个vector<MyStruct>&参数,并对其进行操作。然后,向外部vector<vector<MyStruct>>添加一个新的空元素,并传递对将填充它的代码的引用。

答案 1 :(得分:4)

  

我知道这可以通过以下方式完成   使用指针矢量,但我会   如果可能的话,尽量避免这种情况。

为什么?

这将是最直观/可读/可维护的解决方案,并且比任何人想出的任何奇怪的黑客都要好得多(例如你展示的交换)。

答案 2 :(得分:3)

有一个共同的模式来解决这个问题。这称为智能指针,最好使用的是boost :: shared_ptr。

然后,永远不要按值传递矢量或存储它。相反,存储boost :: shared_ptr&gt;。您不需要关心分配/解除分配(当包含的向量被销毁时,其他的也将如同在代码中一样),并且您可以以几乎相同的方式访问内部成员。但是,通过智能指针对象的引用计数机制避免了该副本。

让我告诉你如何。

using boost::shared_ptr;
vector<shared_ptr<vector<MyStruct> > vecOfVecs;
shared_ptr<vector<MyStruct> > someStructs(new vector<MyStruct>);
// fill in the vector MyStructs
MyStructs->push_back(some struct.... as you usually do).  
//...
vecOfVecs.push_back(someStructs); // Look! No copy!

如果您还没有使用boost :: shared_ptr,我建议您从boost.org下载而不是实现自己的。它真的是不可替代的工具,很快就会出现在C ++标准库中。

答案 3 :(得分:0)

您可以执行类似vect.push_back(vector&lt; MyStruct&gt;());并执行vect.back()。push_back(MyStruct());或使用智能指针,并有一个智能指针向量&lt; MyStruct&gt;

答案 4 :(得分:0)

我认为交换的想法已经很好了,但可以写得更容易:

vecOfVec.push_back(vector<MyStruct>());
vecOfVec.back().swap(someStructs);