• UE4 C++:TSet容器


    目录

    概述

    创建

    添加

    Add:

    Emplace:代替Add,避免插入集合时创建临时文件

    Append:进行合并来插入另一个集合中的所有元素

    迭代

    查询

    Num:查询集合中保存的元素数量

    Contains:查询是否包含特定元素

    FSetElementId:结构体可查找集合中某个键的索引。然后,就可使用该索引与 运算符[] 查找元素

    移除

    Remove 函数可按索引移除元素

    Empty 或 Reset 函数可将集合中的所有元素移除

    排序

    运算符

    Slack

    DefaultKeyFuncs


    概述

    • TSet是一种快速容器类,(通常)用于在排序不重要的情况下存储唯一元素。
    • TSet 类似于 TMap 和 TMultiMap,但有一个重要区别:TSet 是通过对元素求值的可覆盖函数,使用数据值本身作为键,而不是将数据值与独立的键相关联。
    • TSet 可以非常快速地添加、查找和删除元素(恒定时间)。默认情况下,TSet 不支持重复的键,但使用模板参数可激活此行为。
    • TSet 也是值类型,支持常规复制、赋值和析构函数操作,以及其元素较强的所有权。TSet 被销毁时,其元素也将被销毁。键类型也必须是值类型。
    • TSet 会直接使用 运算符== 比较元素,使用 GetTypeHash 对其进行散列,然后使用标准的堆分配器

    创建

    TSet FruitSet; //尚未分配内存
    

    添加

    Add:

    • 如果尝试添加重复键,会替代了旧的条目
    1. FruitSet.Add(TEXT("Banana"));
    2. FruitSet.Add(TEXT("Grapefruit"));
    3. FruitSet.Add(TEXT("Pineapple"));
    4. // FruitSet == [ "Banana", "Grapefruit", "Pineapple" ]
    5. FruitSet.Add(TEXT("Pear"));
    6. FruitSet.Add(TEXT("Banana"));
    7. // FruitSet == [ "Banana", "Grapefruit", "Pineapple", "Pear" ]
    8. // Note:Only one banana entry.

    此处的元素按插入顺序排列,但不保证这些元素在内存中实际保留此排序。如果是新集合,可能会保留插入排序,但插入和删除的次数越多,新元素不出现在末尾的可能性越大。

    Emplace:代替Add,避免插入集合时创建临时文件

    1. FruitSet.Emplace(TEXT("Orange"));
    2. // FruitSet == [ "Banana", "Grapefruit", "Pineapple", "Pear", "Orange" ]

    Append:进行合并来插入另一个集合中的所有元素

    • 集合中的重复键将会替代目标集合中相应的键
    1. TSet FruitSet2;
    2. FruitSet2.Emplace(TEXT("Kiwi"));
    3. FruitSet2.Emplace(TEXT("Melon"));
    4. FruitSet2.Emplace(TEXT("Mango"));
    5. FruitSet2.Emplace(TEXT("Orange"));
    6. FruitSet.Append(FruitSet2);
    7. // FruitSet == [ "Banana", "Grapefruit", "Pineapple", "Pear", "Orange", "Kiwi", "Melon", "Mango" ]

    迭代

    范围for

    1. for (auto& Elem :FruitSet)
    2. {
    3. FPlatformMisc::LocalPrint( *FString::Printf(TEXT(" \"%s\"\n"), *Elem ));
    4. }
    5. // 依次输出 "Banana" "Grapefruit" "Pineapple" "Pear" "Orange" "Kiwi" "Melon" "Mango"

    迭代器

    • CreateIterator 返回拥有读写访问权限的迭代器,
    • reateConstIterator 返回拥有只读访问权限的迭代器
    1. for (auto It = FruitSet.CreateConstIterator(); It; ++It)
    2. {
    3. FPlatformMisc::LocalPrint( *FString::Printf(TEXT("(%s)\n"), *It ) );
    4. }

    查询

    Num:查询集合中保存的元素数量

    int32 Count = FruitSet.Num(); // Count == 8
    

    Contains:查询是否包含特定元素

    1. bool bHasBanana = FruitSet.Contains(TEXT("Banana")); // bHasBanana == true
    2. bool bHasLemon = FruitSet.Contains(TEXT("Lemon")); // bHasLemon == false

    FSetElementId:结构体可查找集合中某个键的索引。然后,就可使用该索引与 运算符[] 查找元素

    在非常量集合上调用 operator[] 将返回非常量引用,而在常量集合上调用将返回常量引用

    1. FSetElementId BananaIndex = FruitSet.Index(TEXT("Banana"));
    2. // BananaIndex is a value between 0 and (FruitSet.Num() - 1)
    3. FPlatformMisc::LocalPrint( *FString::Printf( TEXT(" \"%s\"\n"), *FruitSet[BananaIndex] ));
    4. // Prints "Banana"
    5. FSetElementId LemonIndex = FruitSet.Index(TEXT("Lemon"));
    6. // LemonIndex is INDEX_NONE (-1)
    7. FPlatformMisc::LocalPrint( *FString::Printf(TEXT(" \"%s\"\n"), *FruitSet[LemonIndex] ));
    8. // Assert!

    Find:返回指向元素数值的指针

    • 如果映射不包含该键,则返回null。
    • 对常量集合调用Find,返回的指针也将为常量
    1. FString* PtrBanana = FruitSet.Find(TEXT("Banana")); // *PtrBanana == "Banana"
    2. FString* PtrLemon = FruitSet.Find(TEXT("Lemon")); // PtrLemon == nullptr

    Array:会返回一个 TArray,其中填充了 TSet 中每个元素的一份副本

    • 被传递的数组在填入前会被清空,因此元素的生成数量将始终等于集合中的元素数量
    1. TArray FruitArray = FruitSet.Array();
    2. // FruitArray == [ "Banana","Grapefruit","Pineapple","Pear","Orange","Kiwi","Melon","Mango" ] (order may vary)

    移除

    Remove 函数可按索引移除元素

    1. FruitSet.Remove(0);
    2. // FruitSet == [ "Grapefruit","Pineapple","Pear","Orange","Kiwi","Melon","Mango" ]
    3. int32 RemovedAmountPineapple = FruitSet.Remove(TEXT("Pineapple"));
    4. // RemovedAmountPineapple == 1
    5. // FruitSet == [ "Grapefruit","Pear","Orange","Kiwi","Melon","Mango" ]
    6. int32 RemovedAmountLemon = FruitSet.Remove(TEXT("Lemon"));
    7. // RemovedAmountLemon == 0
    • 仅建议在通过元素迭代时使用:Remove函数会返回已删除元素的数量。如果给定的键未包含在集合中,则会返回0。
    • 如果 TSet 支持重复的键,Remove 将移除所有匹配元素。
    • 移除元素将在数据结构中留下空

    Empty 或 Reset 函数可将集合中的所有元素移除

    1. TSet FruitSetCopy = FruitSet;
    2. // FruitSetCopy == [ "Grapefruit","Pear","Orange","Kiwi","Melon","Mango" ]
    3. FruitSetCopy.Empty();
    4. // FruitSetCopy == []
    • Empty 可采用参数指示集合中保留的slack量,而 Reset 则是尽可能多地留出slack量

    排序

    TSet 可以排序。排序后,迭代集合会以排序的顺序显示元素,但下次修改集合时,排序可能会发生变化。由于排序不稳定,可能按任何顺序显示集合中支持重复键的等效元素。

    • Sort 函数指定排序顺序的二进制谓词
    1. FruitSet.Sort([](const FString& A, const FString& B) {
    2. return A > B; // sort by reverse-alphabetical order
    3. });
    4. // FruitSet == [ "Pear", "Orange", "Melon", "Mango", "Kiwi", "Grapefruit" ] (order is temporarily guaranteed)
    5. FruitSet.Sort([](const FString& A, const FString& B) {
    6. return A.Len() < B.Len(); // sort strings by length, shortest to longest
    7. });
    8. // FruitSet == [ "Pear", "Kiwi", "Melon", "Mango", "Orange", "Grapefruit" ] (order is temporarily guaranteed)

    运算符

    1. TSet NewSet = FruitSet;
    2. NewSet.Add(TEXT("Apple"));
    3. NewSet.Remove(TEXT("Pear"));
    4. // FruitSet == [ "Pear", "Kiwi", "Melon", "Mango", "Orange", "Grapefruit" ]
    5. // NewSet == [ "Kiwi", "Melon", "Mango", "Orange", "Grapefruit", "Apple" ]

    Slack

    DefaultKeyFuncs

    参考链接:

    【UE4 C++ 基础知识】<7> 容器——TSet - 砥才人 - 博客园 (cnblogs.com)

    虚幻引擎中的Set容器 | 虚幻引擎5.0文档 (unrealengine.com)

  • 相关阅读:
    linux线程创建等待及退出总结
    短视频入口打开,重新定义小程序
    微软出品自动化神器【Playwright+Java】系列(十)元素定位详解
    基于新标记方案的实体和关系联合提取
    《UNIX 传奇:历史与回忆》读后感
    WPF图表库LiveCharts的使用
    [Linux 基础] 一篇带你了解linux权限问题
    VMware中Ubuntu(Linux)无法连接网络解决办法记录
    数据库模式与范式 - 数据库的范式化设计
    A-Level物理例题解析及练习Projectile Motion
  • 原文地址:https://blog.csdn.net/Jason6620/article/details/126507373