Skip to content

How do I look up a key in a map without inserting it?

snippet · cpp, stl, map, csharp

Use find(): one lookup, no exception, no insertion. The iterator plays TryGetValue's out parameter. at() is the throwing indexer; operator[] is insert-or-return, a writer's tool that mutates on a read.

examples/cpp/lookup-without-inserting.cpp
// C#: if (settings.TryGetValue("timeout", out var value)) ...
int timeout_or_default(const std::map<std::string, int>& settings) {
if (auto it = settings.find("timeout"); it != settings.end()) {
return it->second; // found: one lookup, no insertion, no exception
}
return 30; // missing: the map is untouched
}
// settings["timeout"] would default-construct a 0 AND insert it: a read
// that writes, which is also why [] does not compile on a const map.
// settings.at("timeout") throws std::out_of_range when the key is missing.

find is TryGetValue with the iterator as the out parameter. Its two siblings do different jobs: at() throws std::out_of_range on a missing key, and operator[] default-constructs a value and inserts it when the key is missing, which is why [] does not compile on a const map. The compiler is telling you it writes.

The same three calls exist on std::unordered_map; the recipe is identical. Since C++20, contains(key) answers the yes-or-no question without an iterator.

Trap: if (settings["timeout"] > 0) on a map that lacks the key inserts timeout = 0 as a side effect of the read. Every later iteration over the map sees it.

Source: https://mkhomutov.github.io/going-unmanaged/F-rosetta-cookbook/#recipe-8--look-up-a-key-without-inserting-it