假设,我有一个班级:
class Class
{
private:
std::vector <std::vector <Type>> vec2d;
// Or, for example, something like this:
std::vector <std::vector <std::shared_ptr <Type>> vec2dptr;
}
我需要组织一个私有向量的接口。矢量的大小可能会增加数千个元素。什么是最佳解决方案(内存/性能)?
作为变体,我可以从getter(begin(),end())返回一对迭代器:
std::pair <std::vector <const std::vector <const Type>>::iterator,
std::vector <const std::vector <const Type>>::iterator>
GetPrimaryVectorRange();
// To get an element from sub-vector, pass iterator of main vector to getter
std::pair <std::vector <const Type>::iterator,
std::vector <const Type>::iterator>
GetSecondaryVectorRange(
std::vector <const std::vector <const Type>>::const_iterator primary_elem );
最简单的方法是通过常量值返回向量,但是然后将调用复制构造函数,而不是从C ++ 11移动构造函数,我是对的吗?在这种情况下是否有任何标准的方法或模式?
答案 0 :(得分:2)
你的API返回一对std::vector
迭代器已经让你公开知道你的2d数组的行是std::vector
s,所以你可以保持它简单并做类似的事情
std::vector<Type> const &operator[](size_t i) const { return vec2d[i]; }
std::vector<Type> &operator[](size_t i) { return vec2d[i]; }
如果需要迭代器,让调用者自己提取迭代器:
auto row = arr[i];
auto iter = std::find(row.begin(), row.end(), 42);
如果数组的所有行长度相同,请考虑编写一个简单的2D数组类(或使用mine)来分配一个块中的所有内存。性能会更好,特别是在您想迭代数组的每个元素的情况下。 (我认为C ++应该在标准中包含这样的类。)
编辑:我意识到我的解决方案与您的解决方案相比确实有一个弱点。如果您决定对所有行使用一个巨大的std::vector
而不是单独的std::vector
,那么它不会破坏基于迭代器的API,但它会破坏我的版本。
另一个选择是返回raw一对原始指针而不是迭代器。它们在迭代器所做的所有相同的地方工作。这仍然会暴露行连续存储的事实,因此您永远不会将单行的元素存储在链表中。但在我看来,连续存储是如此基础,对于任何关心性能的事情都非常重要,因此在API中公开连续性是完全没问题的。
但是,如果它适用于您的需求,我仍然认为使用2D数组包装类是最佳解决方案。