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&
)
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?
CodePudding user response:
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.