Consider the following simple example, where I am using std::equal_to to compare two std::pair<std::string, unsigned>. The operator new is overloaded so that it prints a message when allocations take place (live code here):
#include <functional>
#include <string>
#include <iostream>
// overloaded to see when heap allocations take place
void* operator new(std::size_t n)
{
std::cout << "Allocating " << n << std::endl;
return malloc(n);
}
int main()
{
using key_type = std::pair<std::string, unsigned>;
auto key1 = std::make_pair(std::string("a_______long______string______"), 1);
auto key2 = std::make_pair(std::string("a_______long______string______"), 1);
std::cout << "Finished initial allocations\n\n" << std::endl;
std::equal_to<key_type> eq;
eq(key1, key2); // how can this cause dynamic allocation???
}
The message I am seeing is
Allocating 31
Allocating 31
Finished initial allocations
Allocating 31
Allocating 31
You can see there are two allocations taking place when comparing key1 and key2. But why? std::equal_to's operator takes its arguments by const reference so no allocation should take place... what I am missing? Thanks.