C++ Basics: Insert Map Defaults Without Replacing Existing Values
Configuration defaults should not replace a value that is already present. Use std::map::try_emplace to distinguish a new insertion from an existing entry.
Prepare a scratch directory
Tested on Linux x86_64 with GCC 14.2.0. Install a C++20-capable compiler and its standard-library headers, and make g++ available on PATH. You also need Bash, a text editor, and mktemp, rm, and rmdir. No third-party library is required.
Keep the same terminal open. Stop if setup fails, before saving the source:
start_directory="$PWD"
work_directory="$(mktemp -d)" || exit 1
cd -- "$work_directory" || exit 1Run the example
Save this as map-try-emplace-demo.cpp:
#include <iostream>
#include <map>
#include <string>
int main() {
std::map<std::string, int> retry_limits{{"upload", 3}};
const auto [existing, inserted_existing] = retry_limits.try_emplace("upload", 9);
const auto [created, inserted_new] = retry_limits.try_emplace("download", 5);
std::cout << std::boolalpha;
std::cout << "Upload inserted: " << inserted_existing
<< "; value: " << existing->second << '\n';
std::cout << "Download inserted: " << inserted_new
<< "; value: " << created->second << '\n';
std::cout << "Entries: " << retry_limits.size() << '\n';
}Compile and run it. The && prevents execution if compilation fails:
g++ -std=c++20 -Wall -Wextra -Werror -pedantic map-try-emplace-demo.cpp -o map-try-emplace-demo &&
./map-try-emplace-demoObserved output:
Upload inserted: false; value: 3
Download inserted: true; value: 5
Entries: 2Read the result
The upload entry keeps its original value of three, and the returned flag is false. The missing download entry is created with five and returns true. In either case, the iterator identifies the entry associated with the key.
Apply it carefully
try_emplace does not overwrite an existing value. Use insert_or_assign when replacement is intended. Arguments are still evaluated before the call: passing an expensive function call is not a way to defer that function until insertion succeeds. This example uses the C++17 operation in C++20 mode.
The C++ working draft documents the relevant container behavior. The example uses only features available in C++20, even though the linked draft may include later additions.
Clean up
Remove only the source and executable created here, then remove the empty practice directory:
rm -- map-try-emplace-demo.cpp map-try-emplace-demo
cd -- "$start_directory" || exit 1
rmdir -- "$work_directory"
unset start_directory work_directoryIf the directory is not empty, inspect the remaining contents before removing anything else.
Acknowledgements
This post was created with assistance from AI.