为什么 std::equal_to会导致动态分配?

why would std::equal_to cause dynamic allocation?

本文关键字:动态分配 to std equal 为什么      更新时间:2023-10-16

考虑以下简单示例,我使用std::equal_to来比较两个std::pair<std::string, unsigned>operator new已重载,以便在进行分配时打印一条消息(此处为实时代码(:

#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 allocationsnn" << std::endl;
std::equal_to<key_type> eq;
eq(key1, key2); // how can this cause dynamic allocation???
}

我看到的消息是

Allocating 31
Allocating 31
Finished initial allocations

Allocating 31
Allocating 31

您可以看到在比较key1key2时发生了两个分配。但是为什么?std::equal_to的运算符通过常量引用获取其参数,因此不应进行分配...我错过了什么?谢谢。

这是因为您复制了这些对。

keyX的类型是std::pair<std::string, int>eq有一个函数调用运算符,用于参数const std::pair<std::string, unsigned>&, const std::pair<std::string, unsigned>&。由于类型不匹配,因此引用不能直接绑定到参数。但是,int可以隐式转换为unsigned,因此给定的 pair 可以隐式转换为参数对。

因此,您隐式地为比较创建了一对临时参数。临时字符串的创建会导致内存分配。


如果您使用std::equal_to<>作为比较运算符,则它不会在推断参数类型时创建副本,因此不会导致转换。