简体   繁体   中英

C++ fixed-size vector backed by custom buffer

Is there any STL container that implements a fixed-size vector backed by a custom buffer and allows me do to something like:

int arr[] = {1, 2, 5, 12, 34, 12, 56, 12};
std::mysteryvector<int> vec(arr + 2, 3); // <-- No copy here, and 3 can be a variable
                                         // (no compile-time template parameter)
std::cout << *vec.begin() << std::endl; // prints 5
std::cout << vec.size() << std::endl; // prints 3
// There is no push_back() or resize(), but size(), begin(), end(), etc. 
// work as in std::vector
arr[4] = 1212;
std::cout << vec[2] << std::endl; // prints 1212

Or should I implement it myself? Are hacks/workarounds like using a custom allocator for std::vector recommended?

EDIT. Why ? Compatibility with legacy code that assumes the existence of size() , begin() , end() , [] but does not call push_back() .

There's no such thing, unfortunately.

However, there's a proposal for string_ref and array_ref at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3334.html .

Boost appears to already have implemented string_ref, you can check here: http://www.boost.org/libs/utility/doc/html/string_ref.html .

So you just want something with begin , end , size , and [] ? Would something like this work?

class FakeVector{
    int* m_begin;
    int* m_end;
    size_t m_size;
  public:
    FakeVector(int* begin, size_t size)
      : m_begin(begin), m_end(begin + size), m_size(size) { }

    int* begin()  { return m_begin; }
    int* end()    { return m_end; }
    size_t size() { return m_size; }
    int& operator[] (size_t index) { return m_begin[index]; }

    // And, in case you need const access:
    const int* begin() const { return m_begin; }
    const int* end()   const { return m_end; }
    const int& operator[] (size_t index) const { return m_begin[index]; }
  };


  int arr[] = {1, 2, 5, 12, 34, 12, 56, 12};
  FakeVector vec(arr + 2, 3);
  std::cout << *vec.begin() << std::endl;  // prints 5
  std::cout << vec.size() << std::endl; // prints 3
  arr[4] = 1212;
  std::cout << vec[2] << std::endl; // prints 1212

That's hard-coded to int right now, but that should be fairly simple to templatize.

std::array<int, 3>* mymistvector = new (arr + 2) std::array<int, 3>();

I have a fixed size vector class called fector that acts like a std::vector but has a templated size like std::array. You can find it here . It is a self contained header with 150 LOC

sweet::fector<int,128> f;
for(int i = 0; i < 128; ++i) {
    f.push_back(i);
}

// the next push_back will throw

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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