Main Content

Expensive use of map's bracket operator to insert or assign a value

The bracket operator of std::map or std::unordered_map is used for inserting or assigning a value in the container instead of the insert_or_assign() method, which is more efficient

Since R2022b

Description

This defect occurs when you use the [] operators to insert or assign a value to a key in a std::map or std::unordered_map instead of using the insert_or_assign() method. For instance:

std::map<int, std::string> Data;
Data[55] = "Fifty five"; //defect 
Polyspace® flags the use of the [] operator to insert a key value pair in the map data. This checker applies to code that uses C++17 or later.

Risk

When you insert or assign a value in a std::map or std::unordered_map by using the [] operator, the compiler calls the default constructor of pair to constructs a key-value pair. The method insert_or_assign() inserts or assigns a value without calling the constructor, which makes it more efficient. Using the less efficient [] operator makes your code inefficient.

Fix

When inserting or assigning a value in maps, use their insert_or_assign() method. For instance:

std::map<int, std::string> Data;
Data.insert_or_assign(55,"Fifty five"); 
The insert_or_assign() method inserts the key-value pair without having to construct a pair first, making it more efficient.

Performance improvements might vary based on the compiler, library implementation, and environment that you are using.

Examples

expand all

#include <map>
#include <string>

void foo(std::map<std::string, std::string> &m, std::string name, std::string address)
{
    m[name] = address;                 
}

In this example, the value address is inserted against the key name in the map m. During this insertion a pair (name,address) is formed by calling the default constructor. This method of insertion into a map is inefficient and Polyspace flags it.

Correction — Use the Method insert_or_assign() Instead of []

To fix this defect, use insert_or_assign() instead of [].

#include <map>
#include <string>

void foo(std::map<std::string, std::string> &m, std::string name, std::string address)
{
    m.insert_or_assign(name,address);
}

Result Information

Group: Performance
Language: C++
Default: Off
Command-Line Syntax: EXPENSIVE_MAP_INSERT_OR_ASSIGN
Impact: Low

Version History

Introduced in R2022b