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

时间:2018-10-21 19:59:05

标签: c++ heap-memory std-pair

考虑以下简单示例,其中我使用<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:padding="8dp" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/up" android:text="UP" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/parent" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/up" android:layout_marginBottom="8dp" android:singleLine="true" android:ellipsize="start" tools:text="Parent dir"/> <androidx.recyclerview.widget.RecyclerView android:id="@+id/list" android:layout_below="@id/parent" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/> </RelativeLayout> 比较两个std::equal_tostd::pair<std::string, unsigned>超载,以便在分配发生时显示一条消息(实时代码here):

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 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的运算符通过const引用获取其参数,因此不应该进行分配……我所缺少的是什么?谢谢。

1 个答案:

答案 0 :(得分:29)

这是因为您制作了两对副本。

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

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


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