Хотя «почему» лучше всего читать здесь , есть несколько простых способов получить то, что вы хотите:
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);
Вы даже можете решить, «насколько постоянным» должна быть ваша оболочка и предоставьте конструкторы перемещения (обратите внимание, что t
не является постоянным per se в as_const
), если вы считаете, что это целесообразно для вашего варианта использования.
Обратите внимание, что вы не можете запретить перераспределение вашего вектора таким образом. Если вы хотите это сделать (и не хотите использовать массив размера во время компиляции, поскольку теперь ваш размер только во время выполнения), взгляните на std::unique_ptr<T[]>
. Но обратите внимание, что в этом случае вам сначала нужно создать изменяемый вариант, а затем повторно установить его в константном варианте, поскольку базовый массив инициализируется по умолчанию, и после этого вы ничего не можете изменить.
Конечно, есть и возможность работы с распределителем и запрет перераспределения. Но это не имеет stl-реализации. Есть некоторые реализации для этого типа поведения (я сам попробовал один раз, но это немного беспорядок), но я не знаю, есть ли что-нибудь в надбавке.