Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How do you restrict `resize()` from being called after constructing a vector?

I’m building a class that exposes a sequential container, with a fixed length, but the length isn’t known at compile-time.

So when an instance of my class is constructed, a parameter is passed in, to indicate how big the vector needs to be.

But the length needs to be fixed after construction.
I need to guarantee that the resize() function cannot be invoked, while still allowing other parts of my code to modify individual elements within the vector.
(In other words, I can’t simply expose the vector as vector<T> const&)

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

The same goes for any other function which modifies the length, such as insert(), push_back(), etc.
These functions need to be restricted or hidden.

Is this possible?
Or do I really need to build my own fixed_vector wrapper class to hide the undesired functions?

>Solution :

Since C++20 you can return a std::span to the range in the vector. This allows access to the size and modifiable access to the elements, but not the vector‘s modifiers.

For example:

#include<vector>
#include<span>

class A {
    std::vector<int> vec;
public:
    /*...*/
    auto getVec() {
        return std::span(vec);
    }
 };

The return value can be used as a range, but there is no access to the container interface.

Depending on the types and initialization required, you may also be able to use an array std::unique_ptr instead of a std::vector if you know the size won’t change. However that doesn’t store the size, which you would then need to store yourself:

#include<vector>
#include<span>

class A {
    std::size_t vec_size;
    std::unique_ptr<int[]> vec;
public:
    A(std::size_t size) : vec_size(size), vec(std::make_unique<int[]>(size)) { }

    auto getVec() {
        return std::span(vec, vec_size);
    }
 };

This may be slightly more space efficient since it doesn’t require accounting for a difference in vector size and capacity.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading