为什么 std::equal_to 会导致动态分配?
why would std::equal_to cause dynamic allocation?
考虑以下简单示例,其中我使用 std::equal_to
来比较两个 std::pair<std::string, unsigned>
。 operator new
已过载,因此它会在分配发生时打印一条消息(实时代码 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???
}
我看到的消息是
Allocating 31
Allocating 31
Finished initial allocations
Allocating 31
Allocating 31
比较 key1
和 key2
时,您可以看到发生了两次分配。但为什么? std::equal_to
的运算符通过 const 引用获取其参数,因此不应进行任何分配……我缺少什么?谢谢。
这是因为你复制了对。
keyX
的类型是std::pair<std::string, int>
。 eq
有一个参数 const std::pair<std::string, unsigned>&, const std::pair<std::string, unsigned>&
的函数调用运算符。由于类型不匹配,引用不能直接绑定到参数。但是,int
可隐式转换为 unsigned
,因此给定对可隐式转换为参数对。
因此,您隐式创建了一对用于比较的临时参数。临时字符串的创建导致内存分配。
如果您使用 std::equal_to<>
作为比较运算符,它不会在推导参数类型时创建副本,因此不会导致转换。
考虑以下简单示例,其中我使用 std::equal_to
来比较两个 std::pair<std::string, unsigned>
。 operator new
已过载,因此它会在分配发生时打印一条消息(实时代码 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???
}
我看到的消息是
Allocating 31
Allocating 31
Finished initial allocations
Allocating 31
Allocating 31
比较 key1
和 key2
时,您可以看到发生了两次分配。但为什么? std::equal_to
的运算符通过 const 引用获取其参数,因此不应进行任何分配……我缺少什么?谢谢。
这是因为你复制了对。
keyX
的类型是std::pair<std::string, int>
。 eq
有一个参数 const std::pair<std::string, unsigned>&, const std::pair<std::string, unsigned>&
的函数调用运算符。由于类型不匹配,引用不能直接绑定到参数。但是,int
可隐式转换为 unsigned
,因此给定对可隐式转换为参数对。
因此,您隐式创建了一对用于比较的临时参数。临时字符串的创建导致内存分配。
如果您使用 std::equal_to<>
作为比较运算符,它不会在推导参数类型时创建副本,因此不会导致转换。