为什么 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

比较 key1key2 时,您可以看到发生了两次分配。但为什么? 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<> 作为比较运算符,它不会在推导参数类型时创建副本,因此不会导致转换。