考虑以下简单示例,其中我使用<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_to
。 std::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引用获取其参数,因此不应该进行分配……我所缺少的是什么?谢谢。
答案 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<>
作为比较运算符,则它不会推导参数类型,因此不会创建副本,因此不会引起转换。