简体   繁体   English

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

[英]Build a vector as a subset of another one without copying

Let v be a vector. v是向量。 I would like w to be a subset of v between the indices from and to . 我想w是的一个子集v指数之间的fromto I could just do 我可以这样做

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

However, I do not intend to use v in the future. 但是,我不打算将来使用v As such, I don't need to copy the data between from and to . 因此,我不需要在fromto之间复制数据。 I would need to create a vector who points to v.begin() + from and is of length to - from . 我需要创建一个指向v.begin() + from的向量,并且长度to - from The rest of the memory used by v should be freed. 应该释放v使用的其余内存。 Note that I am fine if it is v being redefined (I can just swap to w afterward if I want to anyway). 请注意,我很好,如果它是v被重新定义(我只是交换到w之后,如果我想反正)。

Is it possible to do that? 有可能吗?

If you want to use a vector , there is no way to avoid copying. 如果要使用vector ,则无法避免复制。 If you want to be sure unused memory is released, you could do it like this : 如果你想确保释放未使用的内存,你可以这样做:

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

This should do the trick with vector. 这应该是矢量的技巧。

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

You should probably use a std::deque, and pop all the elements from begin() to begin() +front, and from end() - to to end(). 您应该使用std :: deque,并将所有元素从begin()跳转到begin()+ front,从end()跳到end()。 That will free the unusded memory minus a tiny chunk from the front of the first bucket and the end of the last bucket. 这样就可以从第一个存储桶的前面和最后一个存储桶的末端中释放出来的内存减去一小部分内存。 std::deque is very performant, since it stores its contents in buckets of arrays. std :: deque非常高效,因为它将其内容存储在数组桶中。 It is not just as performant as vector, but it's in practice probably good enough since its just 1 extra level of indirection. 它不仅仅和矢量一样高效,但它实际上可能足够好,因为它只有一个额外的间接层。 Roughly this is the difference: 大致这是不同的:

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

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

It depends on how much you grow and shrink your vector, but deque shrinks and grows whithout copying any elements ever, its just bucket allocation/deallocation. 它取决于你增长和缩小你的向量,但deque缩小和增长,而不是复制任何元素,它只是桶分配/释放。 So it can be much more performant than vector in some scenarios. 因此,在某些情况下,它可以比矢量更高效。

Should be available soon. 应该很快就会推出。 In the meantime, your options are: 在此期间,您的选择是:

  1. Use std::string<T> rather than vector , and, consequently, std::string_view . 使用std::string<T>而不是vector ,因此使用std::string_view

  2. Craft your own view class. 制作自己的视图类。 Say, 说,

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM