无需复制即可将向量构建为另一个向量的子集

时间:2018-12-13 01:34:36

标签: c++ vector containers move

v为向量。我希望w是索引vfrom之间的to的子集。我可以做

std::vector<T> w(v.begin() + from, v.begin() + to);

但是,我不打算将来使用v。因此,我不需要在fromto之间复制数据。我需要创建一个指向v.begin() + from且长度为to - from的向量。 v使用的其余内存应被释放。请注意,如果重新定义了v,我就很好了(如果需要,我以后也可以交换到w上。)

有可能这样做吗?

4 个答案:

答案 0 :(得分:1)

如果要使用vector,则无法避免复制。如果要确保释放未使用的内存,可以这样:

std::vector<T> w(v.begin() + from, v.begin() + to);
std::vector<T>().swap(v);

答案 1 :(得分:1)

这应该通过矢量来解决问题。

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> v{ 11, 22, 33, 44, 55, 66, 77, 88, 99 };
    constexpr size_t from = 3;
    constexpr size_t to = 7;

    if(to < v.size() - 1)
        v.erase(v.begin() + to, v.end());

    if(from > 0)
        v.erase(v.begin(), v.begin() + from - 1);

    v.shrink_to_fit();

    for(auto i : v)
        cout << i << ' ';
    cout << endl;
}

答案 2 :(得分:0)

您可能应该使用std :: deque,然后将所有元素从begin()弹出到begin()+ front,从end()-到end()。这将释放未使用的内存,从第一个存储桶的前端到最后一个存储桶的末尾减去一小块。 std :: deque的性能很高,因为它将其内容存储在数组的存储桶中。它不仅具有与vector一样的性能,而且在实践中可能还足够好,因为它仅具有1个额外的间接级别。 大致上是这样:

  • std :: vector [i]->返回缓冲区[i]
  • std :: deque [i]-> buckets [i]-> return bucket [i];

参考:https://en.cppreference.com/w/cpp/container/deque

这取决于您增加和减少向量的数量,但是双端队列会在没有复制任何元素的情况下进行收缩和增长,它只是存储区分配/取消分配。因此,在某些情况下,它的性能可能比矢量要好得多。

答案 3 :(得分:0)

Should be available soon.同时,您的选择是:

  1. 使用std::string<T>而不是vector,因此使用std::string_view

  2. 创建自己的视图类。说,

    template<class Iterator> class view {
        Iterator b, e;
    public:
        view(Iterator b, Iterator e): b(b), e(e) {}
    
        auto &operator[](std::size_t i) { return *(b[i]); }
        auto const &operator[](std::size_t i) const { return *(b[i]); }
        auto begin() const { return b; }
        auto end() const { return e; }
        auto size() const { return e - b; }
    };