While the "why" is best read here there are some easy ways to get what you want:
template<class T>
class as_const {
T t;
public:
as_const(T& t_): t(t_) {}
as_const(const as_const&) = default;
as_const(as_const &&) = delete;
as_const& operator=(const as_const&) = default;
as_const& operator=(as_const&&) = delete;
operator const T&() const {
return t;
}
const T& operator*() const {
// Or just a get method, anyway it's nicer to also have an explicit getter
return t;
}
};
std::vector<as_const<int>> vec;
vec.reserve(2)
vec.emplace_back(100);
vec.emplace_back(200);
You even can decide "how constant" your wrapper should be and provide the move constructors (note that t
is not constant per-se in as_const
) if you think that is reasonable for your use-case.
Note that you cannot prohibit the reallocation of your vector in this way. If you want to do that (and don't want to use a compile-time size array since you now your size only at runtime) take a look at std::unique_ptr<T[]>
. But note that in this case you first have to create a mutable variant and then reseat it in a const variant, since the underlying array gets default initialized and you cannot change anything after that.
Of course there is also the possibility of working with an allocator and disallowing a reallocation. But that has no stl-implementation. There are some implementations for this type of behavior out there (I myself gave it a try once but that is a bit of a mess) but I do not know if there is anything in boost.