пользовательский распределитель для std :: unordered_map для установки инкрементного значения - PullRequest
2 голосов
/ 18 марта 2019

У меня есть тип ниже:

std::unordered_map<std::string, int> map;

поле int является индексом для строки, которая будет использоваться другими.Теперь, если кто-то запросит эту карту следующим образом: int id = map["foo"], и если foo отсутствует на карте, то я хочу, чтобы карта добавила новый ключ как foo и установила для него значение map.size() (допустим, ни один элемент не будет удален, поэтому просто используйте map.size (), так как новый индекс будет приемлемым).

Так я могу это сделать?(например, установить распределитель в качестве параметра шаблона)

Или есть какая-то лучшая структура данных для этого?(Я рассматривал набор или неупорядоченный набор, но получение индекса из набора кажется слишком сложным)

1 Ответ

2 голосов
/ 18 марта 2019

Так я могу это сделать? (Например, установить alloctor в качестве параметра шаблона)

Не совсем.Вы можете установить распределитель, но цель распределителя - раздавать память всякий раз, когда контейнер запрашивает ее.Вы не можете предоставить распределитель, который будет делать то, что вы хотите, потому что вы не можете предсказать, как именно контейнер будет использовать ваш распределитель в стандартных реализациях библиотеки.

То, что вы хотите сделать, также является хаком.Распределители должны быть предоставлены только для управления пользовательскими ресурсами памяти, и они не должны ожидать, что они будут делать гораздо больше, чем просто в соответствии с требованиями распределителя стандарта.* в основном a std::unordered_map, но с настройкой на operator[], путь к нему довольно прост:

template<typename K, typename V, typename... OtherArgs>
struct my_uomap : std::unordered_map<K, V, OtherArgs...> {
    using my_uomap::unordered_map::unordered_map; // Inherit the c'tors
    V& operator[](K const& k) {
       // Do something custom
    }
    // And the other overload too
};

Не позволяйте скептикам пугать вас наследованием из стандартного контейнера библиотеки,Это проблема только тогда, когда вы удаляете объекты полиморфно.Это редко, как стандартные контейнеры используются, хотя вы должны помнить об этом.

...