V838. Temporary object is constructed during lookup in ordered associative container. Consider using a container with heterogeneous lookup to avoid construction of temporary objects.
The analyzer has detected a call to the lookup function in an ordered associative container ('std::set', 'std::multiset', 'std::map', or 'std::multimap') with an argument whose type differs from the container's key type. This call results in the creation of a temporary object with the key type from the passed argument.
If type conversion is an expensive operation (for example, 'const char *' to 'std::string'), it may affect application performance.
Starting with C++14, you can avoid creating a temporary object. This requires the comparator of the ordered associative container to support the heterogeneous lookup. For this to happen, the following conditions must be met:
- The comparator is able to compare the argument type with the key type.
- The 'is_transparent' alias is declared in the comparator.
The analyzer issues a warning if the 'is_transparent' name is not declared in the comparator.
Let's take a look at the example:
void foo(const char *str)
{
static std::set<std::string> cont;
auto it = cont.find(str); // <=
if (it != cont.end())
{
// do smth
}
}
In the example above, the 'cont' container is declared with the comparator of the 'std::less<std::string>' type by default. This comparator does not support heterogeneous lookup. Therefore, each call to the 'find' function creates a temporary 'std::string' object from 'const char *'.
To avoid creating a temporary object of the 'std::string' type, use a container with a comparator that supports heterogeneous lookup and can compare 'std::string' with 'const char *'. For example, you can use 'std::set' with the 'std::less<>' comparator:
void foo(const char *str)
{
static std::set<std::string, std::less<>> cont;
auto it = cont.find(str);
if (it != cont.end())
{
// do smth
}
}
Now, when calling the 'find' function, a temporary object of the 'std::string' type is not created, and an argument of the 'const char *' type is directly compared with the keys.