将范围拆分为子范围
我有一个容器 std::vector,我想将其有效地分成子范围,每个子范围包含 x 项。不需要原始容器,因此应移动项目而不是将其复制到子范围中。
我已经设法使用复制来进行分割,但是我不确定如何通过移动分配来进行分割?
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);
}
I have a container std::vector and I would like to efficiently split it into sub-ranges with x items in each. The original container is not needed so the items should be moved and not copied into the sub-ranges.
I've managed to do the splitting using copying, however I'm unsure how to do it with move assignments?
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());
}
EDIT:
Some progress... still not quite there, and a bit ugly
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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有一个问题:您听说过
View
概念吗?这个想法是,您只需创建一个“视图”(代理模式)来限制/改变您对数据的看法,而不是实际移动数据。
例如,对于范围,一个非常简单的实现是:
Boost.Range 提供了一个胖版本,包含很多东西。
在这种情况下,优点有很多。其中:
向量
,因此具有更好的内存局部性以下是使用此方法的
分割
:当然,只有当您可以保留
range
对象时,这才有效。关于您的原始算法:这里使用
while
循环是虚假的,并迫使您使用比必要的更多的move
。我制作的 for 循环在这方面应该要好得多。One question: have you ever heard of the
View
concept.The idea is that instead of actually moving the data, you just create a "view" (Proxy pattern) that will restrict / change your perception of it.
For example, for a range, a very simple implementation would be:
Boost.Range
offers a fat version, with a lot of things.The advantages are numerous in this case. among which:
vector
, thus better memory localityHere is the
split
with this method:Of course, this only works if you can keep the
range
object around.Regarding your original algorithm: the use of a
while
loop is spurious here, and forces you to use much moremove
s than necessary. Thefor
loop I crafted should be much better in this regard.您可以在
中使用std::make_move_iterator
将迭代器包装到move_iterator
中。该迭代器将std::move
取消引用其基本迭代器的结果,从而允许将其移动到其他地方。编辑:就像您发现的那样,
std::move()
和make_move_iterator
之间存在映射:因此您发现哪个更干净取决于您。 (第一个,对我来说。)
You can use
std::make_move_iterator
in<iterator>
to wrap your iterator into amove_iterator
. This iterator willstd::move
the result of dereferencing its base iterator, allowing that to be moved elsewhere.EDIT: And like you found, there's a mapping between
std::move()
andmake_move_iterator
:So which you find cleaner is up to you. (The first one, to me.)