Вопрос про неизменяемость поля first (key) в стандартных контейнерах типа Отображение
Скажите, пожалуйста, правильно ли я понимаю, что стандартные контейнеры C++ типа Отображение хранят внутри себя пары, поле first которых является const? Или же внутри контейнеров хранятся пары с изменяемым полем first, но пользователь видит это поле (например - через итераторы) со спецификатором const при помощи какой-то хитрой магии?
Я спрашиваю, потому что решаю задачу написания отображения, которое вместо динамической аллокации элементов использует пул заранее созданных (пустых) объектов. И я столкнулся с нюансом: отображение должно быть в состоянии менять поле first, но пользователь должен видеть соответствующее поле со спецификатором const.
Единственная законная идея, которая пришла мне на ум, - это использование прокси-обертки. Такой подход имеет ряд минусов.
Использует ли стандартная библиотека такой же подход или же какую-то магию, - я понять не смог, исходники STL находятся за пределами моего понимания.
Ответы (1 шт):
Начинка std::map зависит от реализации. Но раз из нее можно достать ссылку на std::pair<const A, B> и не нарушить strict aliasing, то внутри она скорее всего будет хранить тот же тип, с константным ключом.
отображение должно быть в состоянии менять поле
first
Есть вариант вызывать деструктор ключа (или всей пары), а затем конструктор ключа с помощью placement-new. Получившиеся пары перед использованием пропускать через std::launder.
Не уверен точно, но кажется, начиная с С++20 launder не обязателен, если сам пересоздаваемый объект неконстантный (даже если у него есть константные поля).