我有一个容器 std::vector,我想有效地将它分成子范围,每个子范围有 x 个项目。不需要原始容器,因此应 move 项目而不是将其复制到子范围中。
我已经设法使用复制进行拆分,但是我不确定如何使用 move 分配进行拆分?
range.insert(range.end(), new_items.begin(), new_items.end());
while(range.size() >= x)
{
sub_ranges.push_back(std::vector<int>(range.begin(), range.begin() + x));
range = std::vector<int>(range.begin() + x, range.end());
}
编辑:
一些进步......仍然不完全,而且有点丑
while(range.size() >= x)
{
std::vector<short> sub_range(x); // Unnecessary allocation?
std::move(range.begin(), range.begin() + x, sub_range.begin());
sub_ranges_.push_back(std::move(sub_range));
std::move(range.begin() + x, range.end(), range.begin());
range.resize(range.size() - x);
}
最佳答案
一个问题:你听说过View
这个概念吗。
这个想法是,您无需实际 move 数据,而只需创建一个“ View ”(代理模式)来限制/改变您对它的看法。
例如,对于一个范围,一个非常简单的实现是:
template <typename Iterator>
struct Range
{
Iterator mBegin, mEnd;
};
Boost.Range
提供了一个胖版本,有很多东西。
在这种情况下,优点很多。其中:
- 单个
vector
,因此更好的内存位置 - 拆分很容易,不涉及任何数据的 move/复制
这是使用此方法进行的拆分
:
typedef Range<std::vector<int>::iterator> range_type;
std::vector<range_type> split(std::vector<int> const& range, size_t x)
{
std::vector<range_type> subRanges;
for (std::vector<int>::iterator it = range.begin(), end = range.end();
it != end; it += std::min(x, (size_t)std::distance(it,end)))
{
subRanges.push_back(range_type(it,end));
}
return subRanges;
}
当然,这只有在您可以保留 range
对象的情况下才有效。
关于您的原始算法:while
循环的使用在这里是虚假的,并迫使您使用比必要更多的 move
。我设计的 for
循环在这方面应该好得多。
关于c++ - 将范围拆分为子范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4139710/