Копировать подмножество std :: map
Я пытаюсь скопировать подмножество структуры std :: map в новую структуру карты наиболее эффективным способом. Я могу думать только о простом ванильном решении, как это:
Есть лучший способ сделать это?
Решение
Метод вставки позволяет вам указать диапазон следующим образом:
Другие решения
Вы можете использовать конструктор диапазона карты (c ++ 11):
и если вам нужен более старый стандарт:
И вставка тоже работает
Если вы хотите дополнительной гибкости при выборе копируемых элементов, copy_if обеспечим это:
Это немного сложно использовать для std::map (а также, например, std::set ), но std::inserter работает хорошо.
Конечно проще std::copy может быть использован аналогично конструктору диапазона.
Copy std::map data to another map
Sometimes this work properly, sometimes this copies only the keys and the value 0. Where is my mistake here?
2 Answers 2
Copying one map to another can be done with operator = or the copy constructor.
The code you’ve posted above will work correctly assuming that Amap2 is empty. If you try to insert a key/value pair into a map that already holds that key, then the old value will be kept and the new one will be discarded. For that reason, if you write
In some circumstances you might not copy everything over as intended, because duplicate keys won’t copy.
To set Amap2 equal to Amap1 , consider just using the assignment operator:
This will blindly discard the contents of Amap2 , though, so be careful when doing this.
If what you want to do is add all the key/value pairs from Amap2 into Amap1 in a way that completely overrides the existing key/value pairs, you can do so using the following logic. The idea here is similar to the logic behind mergesort — we treat the maps as sequences of sorted values and then continuously blend the two together:
Как скопировать unordered_map с помощью константного ключа?
PS : Я прочитал ответ на аналогичный вопрос:
Ассоциативные контейнеры предоставляют только пару (ключ, значение) как std :: pair, поэтому дополнительная константа для типа ключа является излишней.
Но это не объясняет, почему хэш-карта с ключом const практически непригодна для использования и как обойти проблему.
1 ответ
Использует третий параметр по умолчанию std::hash<const int> . Этот тип хэша, в отличие от std::hash<int> , не является специализированным в стандартной библиотеке, как и deleted (как указано в сообщении об ошибке).
При копировании unordered_set требуется рабочий хеш. Чтобы сделать рабочий хеш:
Вы можете специализировать std::hash<const int> самостоятельно, чтобы он больше не удалялся:
Или вы можете явно указать свой хеш:
Или вы можете избавиться от константы в ключе (так как это не имеет никакого эффекта):
Приложение :
Удалено означает, что конструктор неспециализированного std::hash удален:
Под «удаленным» это означает, что он не существует (ни предоставлен пользователем, ни установлен по умолчанию).
Вы можете увидеть это на странице cppreference, где используется терминология «включено / отключено». :
Для каждого типа Key, для которого ни библиотека, ни пользователь не предоставляют включенную специализацию std :: hash, эта специализация существует и отключена.
Поскольку std::hash<const int> не предоставляется библиотекой, он отключен, если он не предоставлен пользователем. Далее в тексте объясняется, что такое отключено :
Отключенные специализации не удовлетворяют Hash, [. ] std :: is_default_constructible_v, std :: is_copy_constructible_v [. ] все ложны. Другими словами, они существуют, но их нельзя использовать.
Итак, эти конструкторы должны быть недоступны (и удаление их — лучший способ сделать это).
Как скопировать одну карту в другую с помощью std :: copy?
Я хотел бы скопировать содержимое одной std :: map в другую. Могу ли я использовать std::copy для этого? Очевидно, следующий код работать не будет:
Это не сработает, потому что copy позвоню operator* on m2.begin() для «разыменования» его и присвоения значения (все значения имеют тип std::pair<const int, double> ). Тогда он позвонит operator++ перейти к следующему месту в m2 . Обе эти операции не работают из-за const in const int и нет места для каких-либо новых элементов.