将范围分成子范围 [英] Splitting range into sub-ranges

查看:71
本文介绍了将范围分成子范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个容器std :: vector,我想有效地将​​其拆分为子区域,每个子区域中有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());
    }

有些进步...仍然还不够,而且有点丑陋

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);
    }

推荐答案

您可以在<iterator>中使用std::make_move_iterator将迭代器包装为move_iterator.此迭代器将std::move取消引用其基本迭代器的结果,从而可以将其移至其他位置.

You can use std::make_move_iterator in <iterator> to wrap your iterator into a move_iterator. This iterator will std::move the result of dereferencing its base iterator, allowing that to be moved elsewhere.

// assuming I understand your code, which I don't
range.insert(range.end(), new_items.begin(), new_items.end());
while(range.size() >= x)
{
    auto first = std::make_move_iterator(range.begin());
    auto last = std::make_move_iterator(range.begin() + x);

    sub_ranges.push_back(std::vector<int>(first, last));
    range = std::vector<int>(range.begin() + x, range.end());
}


就像您发现的那样,在std::move()make_move_iterator之间存在一个映射:


And like you found, there's a mapping between std::move() and make_move_iterator:

std::move(first, last, out); // is the same as
std::copy(std::make_move_iterator(first), std::make_move_iterator(last), out);

因此,您可以根据自己的意愿选择清洁剂. (第一个,对我来说.)

So which you find cleaner is up to you. (The first one, to me.)

这篇关于将范围分成子范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆