Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unintrusive way to enforce size constraint on std::vector?

Tags:

c++

I want to have a certain kind of std::vector that cannot have more than const int MAX_LENGTH elements. I understand that I cannot override std::vector non-virtual functions, which I'd need to do to put a size check in all the relevant member functions (e.g., assign, push_back...there are so many). The most obvious way to do this is to wrap std::vector in a class that ensures no operation adds beyond the maximum length. But this seems clunky. Is there a more elegant solution than a wrapper class to limit std::vector size?

like image 720
helloB Avatar asked Jul 31 '15 16:07

helloB


People also ask

How do I fix the size of a vector in C++?

The C++ function std::vector::resize() changes the size of vector. If n is smaller than current size then extra elements are destroyed. If n is greater than current container size then new elements are inserted at the end of vector.

How do you reserve the size of a vector?

std::vector class provides a useful function reserve which helps user specify the minimum size of the vector.It indicates that the vector is created such that it can store at least the number of the specified elements without having to reallocate memory. Each vector object has two parameters–size and capacity.

What does std::vector resize do?

vector::resizeResizes the container to contain count elements. If the current size is greater than count, the container is reduced to its first count elements.

Does push back increase vector size?

push_back effectively increases the vector size by one, which causes a reallocation of the internal allocated storage if the vector size was equal to the vector capacity before the call.


1 Answers

Are you sure that the vector itself can't grow, or that merely the consumers of such a vector need to limit the size of the arguments? If it's the latter, then simply assert(arg.size() <= MAX_LENGTH) where needed, document it, and be done. Otherwise, read on.

A std::vector can have unlimited size. If you limit that size, it's not a std::vector anymore. So, you cannot publicly derive from std::vector and limit the size without breaking the Liskov Substitution Principle. The derived class is still a vector, but doesn't act as one, and can't be used as one, and such an interface will thoroughly confuse your users, and the compiler will not catch serious usage bugs that will ensue. It's a bad idea.

The best you can do is to privately derive from vector, or have-a vector as a member, and expose all of the vector's interfaces while enforcing the size. Such a vector must not be convertible to std::vector, although obviously you can allow it to be copied or moved to a std::vector. It'll still perform just as well as a vector would, will still allow access via iterators, etc.

We're talking of a very small class, and its implementation simply has to follow the standard (or at least the cpp reference), you're leaving all the real work to the private std::vector. So that's not clunky, that's the only sane way to do it.

like image 56
Kuba hasn't forgotten Monica Avatar answered Sep 27 '22 18:09

Kuba hasn't forgotten Monica