Skip to content

43 Intermediate The Hundred

The Insert That Did Nothing

no error, no warning, and no change

#include <iostream>
#include <map>
#include <string>

int main() {
    std::map<std::string, int> price{{"widget", 10}, {"gadget", 25}};

    const std::map<std::string, int> sale{{"widget", 7}, {"doodad", 3}};
    for (const auto& item : sale)
        price.insert(item);   // apply the sale prices

    for (const auto& [name, cost] : price)
        std::cout << name << ": " << cost << '\n';
}

Run it. What is the widget on sale for?

Answer
doodad: 3
gadget: 25
widget: 10

The brand-new doodad went in at 3. The widget is still full price.

Why

map::insert means insert if absent. "widget" was already a key, so the container kept the existing element and dropped your 7 on the floor — no exception, no warning, nothing at the call site. "doodad" was new, so that one landed, which is what makes the bug so convincing: half the loop works. insert does report what happened — it returns a std::pair<iterator, bool> whose .second is false when the key already existed (checking it here prints inserted=0, with the iterator pointing at the old 10) — but that return value is not [[nodiscard]], so ignoring it is perfectly quiet; g++ 11 compiles this clean under -Wall -Wextra. emplace and insert with a hint decline in exactly the same way, and the mirror-image trap is operator[], which inserts when you only meant to read (entry 24).

The fix

Look at the bool, or call something that says "overwrite":

auto [pos, inserted] = price.insert(item);   // and actually branch on `inserted`

price[name] = cost;                          // assignment always overwrites
price.insert_or_assign(name, cost);          // C++17, and it says so in the name

The last two leave widget: 7; the first at least tells you when nothing changed.

Takeaway: insert never overwrites — it declines, and it says so only through a bool you have to bother reading.

Try it: g++ -std=c++17 main.cpp -o demo && ./demo

Open in Compiler Explorer ↗ Quiz this entry