Ответ на этот вопрос также зависит от того, насколько дорого стоит создать тип значения, который вы храните на карте:
typedef std::map <int, int> MapOfInts;
typedef std::pair <MapOfInts::iterator, bool> IResult;
void foo (MapOfInts & m, int k, int v) {
IResult ir = m.insert (std::make_pair (k, v));
if (ir.second) {
}
else if ( replaceEntry ( ir.first->first ) ) {
ir.first->second = v;
}
}
Для типа значения, такого как int, приведенное выше будет более эффективным, чем поиск с последующей вставкой (при отсутствии оптимизации компилятора). Как указано выше, это связано с тем, что поиск по карте выполняется только один раз.
Однако для вызова insert требуется, чтобы у вас уже было сконструировано новое «значение»:
class LargeDataType { };
typedef std::map <int, LargeDataType> MapOfLargeDataType;
typedef std::pair <MapOfLargeDataType::iterator, bool> IResult;
void foo (MapOfLargeDataType & m, int k) {
LargeDataType const & v = VeryExpensiveCall ( );
IResult ir = m.insert (std::make_pair (k, v));
if (ir.second) {
}
else if ( replaceEntry ( ir.first->first ) ) {
ir.first->second = v;
}
}
Чтобы вызвать 'insert', мы платим за дорогостоящий вызов для создания нашего типа значения - и, судя по тому, что вы сказали в вопросе, вы не будете использовать это новое значение в 20% случаев. В приведенном выше случае, если изменение типа значения карты не является вариантом, более эффективно сначала выполнить «поиск», чтобы проверить, нужно ли нам создавать элемент.
В качестве альтернативы тип значения карты можно изменить, чтобы сохранить дескрипторы данных, используя ваш любимый тип интеллектуального указателя. Вызов insert использует нулевой указатель (очень дешево для создания), и только в случае необходимости создается новый тип данных.