Відповідь на це питання також залежить від того, наскільки дорого створювати тип значення, який ви зберігаєте на карті:
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) {
// insertion took place (ie. new entry)
}
else if ( replaceEntry ( ir.first->first ) ) {
ir.second->second = v;
}
}
Для типу значення, такого як int, вищезазначене буде більш ефективним, ніж пошук, за яким слід вставка (за відсутності оптимізації компілятора). Як зазначено вище, це тому, що пошук по карті відбувається лише один раз.
Однак для виклику для вставки потрібно, щоб у вас вже було побудовано нове "значення":
class LargeDataType { /* ... */ };
typedef std::map <int, LargeDataType> MapOfLargeDataType;
typedef std::pair <MapOfLargeDataType::iterator, bool> IResult;
void foo (MapOfLargeDataType & m, int k) {
// This call is more expensive than a find through the map:
LargeDataType const & v = VeryExpensiveCall ( /* ... */ );
IResult ir = m.insert (std::make_pair (k, v));
if (ir.second) {
// insertion took place (ie. new entry)
}
else if ( replaceEntry ( ir.first->first ) ) {
ir.second->second = v;
}
}
Для того, щоб зателефонувати "вставити", ми платимо за дорогий дзвінок, щоб побудувати наш тип значення - і з того, що ви сказали у питанні, ви не будете використовувати це нове значення 20% часу. У наведеному вище випадку, якщо зміна типу значення карти не є можливістю, то ефективніше спочатку виконати "пошук", щоб перевірити, чи потрібно нам створювати елемент.
Крім того, тип значення карти можна змінити для збереження дескрипторів даних, використовуючи ваш улюблений тип розумного вказівника. Виклик для вставки використовує нульовий покажчик (дуже дешевий для побудови) і лише за необхідності створюється новий тип даних.