допустим, у меня есть карта, ключ которой — пара, а пользовательский компаратор гарантирует уникальность по отношению к первому элементу этой пары.
class comparator
{
public:
bool operator()(const std::pair<std::string, std::int>& left,
const std::pair<std::string, std::int>& right)
{
return left.first < right.first;
}
};
std::map<std::pair<std::string, std::int>, foo, comparator>;
Теперь я хотел бы, чтобы эта карта была более умной, чем это, если возможно.
Вместо того, чтобы быть отклоненным во время вставки в случае, если ключ с той же строкой, что и первый элемент пары, уже существует, я бы перезаписал «уже существующий элемент», если целое число (.second) пары в «возможно, будет вставленный элемент «больше.
Конечно, я могу сделать это, посмотрев на карту ключ, получив детали ключа и переписав его при необходимости.
В качестве альтернативы я мог бы применить подход после вставки с мультикартой, поверх которой я бы повторил, чтобы очистить дубликаты, сохраняя только ключ с наибольшим целым числом пары.
Вопрос в том, могу ли я сделать это изначально, переопределив часть реализации stl (оператор [] — метод вставки) или улучшив мой собственный компаратор, а затем просто полагаясь на метод вставки карты?
Я не знаю, принято ли это, но мы могли бы представить себе неконстантный компилятор, который мог бы обновлять уже сохраненную пару (ключ, значение) при определенных обстоятельствах.
ЗначениеВ ответ на ваш вопрос, что вы не можете сделать это.
Есть две проблемы с вашей предполагаемой реализацией:
std::map
все равно вставит элемент до или после left
на основании возврата компаратораРешение проблемы — то, что предлагает @MvG. Ваш ключ не должен быть спаренным, это ваша ценность, которая должна быть спарена.
Это дает дополнительное преимущество: вам не нужен пользовательский компаратор.
Проблема в том, что вам понадобится пользовательский вставщик:
std::pair< int, foo >& tempValue = _myMap[ keyToInsert ];
if( valueToInsert.first >= tempValue.first )
{
tempValue = valueToInsert;
}
Обратите внимание, что это будет работать только если все valueToInsert.first
Если вы используете положительные значения, вызывайте конструктор по умолчанию для int
0. Если у вас был отрицательный valueToInsert.first
Если вместо вашего элемента будет вставлена пара созданных по умолчанию значений.
Других решений пока нет …