У меня есть такой код:
std::map<int, const Data> all_data;
// ...
bool OldDataIsBetter(Data const& oldData, Data const& newData) {...}
// ...
void AddData(int key, Data&& newData)
{
auto [it, ok] = all_data.try_emplace(key, std::move(newData));
if (!ok)
{
if (OldDataIsBetter(*it, newData)) return;
it->second = std::move(newData);
}
}
Это не компилируется, потому что it->second
относится к const Data
и поэтому его оператор присваивания не может быть вызван. Это прекрасно работает, если const
удалено.
Цель вышеизложенного - insert_or_assign
, за исключением того, что если элемент уже присутствует, мне нужно сравнить старый и новый элементы, чтобы увидеть, какой из них «лучше».
Цель объявления типа элемента карты с помощью const
состоит в том, что данные должны быть неизменными один раз на карте - элемент в целом может быть заменен, но не может быть изменен по частям.
Я могу «исправить» вышеприведенное , переназначив контейнер вместо:
all_data[key] = std::move(newData);
(Фактически получается, что та же проблема с const
.)
Или стирая и повторяя emplace:
all_data.erase(it);
all_data.emplace(key, std::move(newData)); // should never fail
Но ни один из них не выглядит элегантным, так как у меня уже есть итератор, указывающий на элемент, который должен быть заменен, и оба из вышеперечисленных забудьте об этом и go выполните поиск снова.
Есть ли лучший способ выполнить sh эту замену?
TLDR из цепочки чата поднял связанные вопросы:
- Если
extract
, можно Извлеките узел из контейнера, позвольте вам изменить его иначе-const ключ и заново вставить его - все без каких-либо перераспределений - почему это невозможно для const mapped_value? - Const объекты могут быть уничтожены. Это также должно применяться к const-объектам внутри контейнеров - и это действительно то, что может делать вариант erase / emplace, если случается повторное использование одного и того же хранилища для узла (либо по совпадению, либо через пользовательский распределитель). Почему же тогда нет способа
replace
const mapped_value с другим const mapped_value без перераспределения узла карты, в котором он находится?