首页 > 编程语言 >UE5 C++ TSet

UE5 C++ TSet

时间:2023-06-22 20:33:08浏览次数:36  
标签:TSet TEXT 元素 Pear C++ Orange Grapefruit UE5 FruitSet

概念

  • TSet是一种快速容器类,用于在排序不重要的情况下存储唯一元素
  • TSet 也是值类型,支持常规复制、赋值和析构函数操作,以及其元素较强的所有权
  • TSet 被销毁时,其元素也将被销毁。键类型也必须是值类型

创建

  TSet<FString> FruitSet;

添加元素

  • Add 将提供键加入set

     FruitSet.Add(TEXT("Banana"));
     FruitSet.Add(TEXT("Grapefruit"));
     FruitSet.Add(TEXT("Pineapple"));
     // FruitSet == [ "Banana", "Grapefruit", "Pineapple" ]
    
     FruitSet.Add(TEXT("Pear"));
     FruitSet.Add(TEXT("Banana"));
     // FruitSet == [ "Banana", "Grapefruit", "Pineapple", "Pear" ]
     // Note:Only one banana entry.
    
  • 使用Emplace代替Add,避免插入集合时创建临时文件

  FruitSet.Emplace(TEXT("Orange")); // FruitSet == [ "Banana", "Grapefruit", "Pineapple", "Pear", "Orange" ]
  • Append函数来插入另一个集合中的所有元素
    Set<FString> FruitSet2;
    FruitSet2.Emplace(TEXT("Kiwi"));
    FruitSet2.Emplace(TEXT("Melon"));
    FruitSet2.Emplace(TEXT("Mango"));
    FruitSet2.Emplace(TEXT("Orange"));
    FruitSet.Append(FruitSet2);
    // FruitSet == [ "Banana", "Grapefruit", "Pineapple", "Pear", "Orange", "Kiwi", "Melon", "Mango" ]
    

迭代

  • for-range
    for (auto& Elem :FruitSet)
        {
            FPlatformMisc::LocalPrint(
                *FString::Printf(
                    TEXT(" \"%s\"\n"),
                    *Elem
                )
            );
        }
        // Output:
        //  "Banana"
        //  "Grapefruit"
        //  "Pineapple"
        //  "Pear"
        //  "Orange"
        //  "Kiwi"
        //  "Melon"
        //  "Mango"
    
  • 迭代器
    • CreateIterator 返回拥有读写访问权限的迭代器
    • CreateConstIterator 返回拥有只读访问权限的迭代器
     for (auto It = FruitSet.CreateConstIterator(); It; ++It)
        {
            FPlatformMisc::LocalPrint(
                *FString::Printf(
                    TEXT("(%s)\n"),
                    *It
                )
            );
        }
    

查询

  • Num函数可查询集合中保存的元素数量
      int32 Count = FruitSet.Num();  // Count == 8
    
  • Contains函数确定集合是否包含特定元素
 bool bHasBanana = FruitSet.Contains(TEXT("Banana"));   // bHasBanana == true
 bool bHasLemon = FruitSet.Contains(TEXT("Lemon"));  // bHasLemon == false
  • FSetElementId 结构体可查找集合中某个键的索引

    • 可使用该索引与 operator[] 查找元素
    • 在非常量集合上调用 operator[] 将返回非常量引用,而在常量集合上调用将返回常量引用
    FSetElementId BananaIndex = FruitSet.Index(TEXT("Banana"));
        // BananaIndex is a value between 0 and (FruitSet.Num() - 1)
        FPlatformMisc::LocalPrint(
            *FString::Printf(
                TEXT(" \"%s\"\n"),
                *FruitSet[BananaIndex]
            )
        );
        // Prints "Banana"
    
        FSetElementId LemonIndex = FruitSet.Index(TEXT("Lemon"));
        // LemonIndex is INDEX_NONE (-1)
        FPlatformMisc::LocalPrint(
            *FString::Printf(
                TEXT(" \"%s\"\n"),
                *FruitSet[LemonIndex]
            )
        ); // Assert!
    
  • Find 将返回指向元素数值的指针

    • 如果映射不包含该键,则返回nullptr
    • 对常量集合调用Find,返回的指针也将为常量
     FString* PtrBanana = FruitSet.Find(TEXT("Banana")); // *PtrBanana == "Banana"
     FString* PtrLemon = FruitSet.Find(TEXT("Lemon")); //  PtrLemon == nullptr
    
  • Array函数会返回一个TArray,其中填充了TSet中每个元素的一份副本

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

移除元素

  • Remove 可按索引移除元素
    • Remove 函数会返回已删除元素的数量
    • 如果给定的键未包含在集合中,则会返回0
    • 如果TSet支持重复的键,Remove将移除所有匹配元素
    FruitSet.Remove(0);  // FruitSet == [ "Grapefruit","Pineapple","Pear","Orange","Kiwi","Melon","Mango" ]
    int32 RemovedAmountPineapple = FruitSet.Remove(TEXT("Pineapple"));  // RemovedAmountPineapple == 1
    // FruitSet == [ "Grapefruit","Pear","Orange","Kiwi","Melon","Mango" ]
    FString RemovedAmountLemon = FruitSet.Remove(TEXT("Lemon")); // RemovedAmountLemon == 0
    
  • EmptyReset 函数可将集合中的所有元素移除
    • Empty 可采用参数指示集合中保留的slack量,而 Reset 则是尽可能多地留出slack量
    TSet<FString> FruitSetCopy = FruitSet;
        // FruitSetCopy == [ "Grapefruit","Pear","Orange","Kiwi","Melon","Mango" ]
    
        FruitSetCopy.Empty();
        // FruitSetCopy == []
    

排序

  • TSet可以排序。排序后,迭代集合会以排序的顺序显示元素,但下次修改集合时,排序可能会发生变化。由于排序不稳定,可能按任何顺序显示集合中支持重复键的等效元素
  • Sort 函数使用指定排序顺序的二进制谓词
 FruitSet.Sort([](const FString& A, const FString& B) {
        return A > B; // sort by reverse-alphabetical order
    });
    // FruitSet == [ "Pear", "Orange", "Melon", "Mango", "Kiwi", "Grapefruit" ] (order is temporarily guaranteed)

    FruitSet.Sort([](const FString& A, const FString& B) {
        return A.Len() < B.Len(); // sort strings by length, shortest to longest
    });
    // FruitSet == [ "Pear", "Kiwi", "Melon", "Mango", "Orange", "Grapefruit" ] (order is temporarily guaranteed)

运算符

  • TArray一样,TSet是常规值类型,可通过标准复制构造函数或赋值运算符进行复制
  • 因为集合严格拥有其元素,复制集合的操作是深层的,所以新集合将拥有其自身的元素副本
 TSet<FString> NewSet = FruitSet;
 NewSet.Add(TEXT("Apple"));
 NewSet.Remove(TEXT("Pear"));
 // FruitSet == [ "Pear", "Kiwi", "Melon", "Mango", "Orange", "Grapefruit" ]
 // NewSet == [ "Kiwi", "Melon", "Mango", "Orange", "Grapefruit", "Apple" ]

Slack

  • Slack是不包含元素的已分配内存
  • 调用 Reserve可分配内存,无需添加元素
  • 通过非零slack参数调用ResetEmpty 可移除元素,无需将其使用的内存取消分配
  • Slack优化了将新元素添加到集合的过程,因为可以使用预先分配的内存,而不必分配新内存
  • 它在移除元素时也十分实用,因为系统不需要将内存取消分配
  • 在清空希望用相同或更少的元素立即重新填充的集合时,此方法尤其有效
    FruitSet.Reset();  // FruitSet == [ <invalid>, <invalid>, <invalid>, <invalid>, <invalid>, <invalid> ]
    
     FruitSet.Reserve(10);
     for (int32 i = 0; i < 10; ++i)
      {
          FruitSet.Add(FString::Printf(TEXT("Fruit%d"), i));
      }
      // FruitSet == [ "Fruit9", "Fruit8", "Fruit7" ..."Fruit2", "Fruit1", "Fruit0" ]
    
  • Shrink 将从容器的末端移除所有slack,但这会在中间或开始处留下空白元素
     // Remove every other element from the set.
        for (int32 i = 0; i < 10; i += 2)
        {
            FruitSet.Remove(FSetElementId::FromInteger(i));
        }
        // FruitSet == ["Fruit8", <invalid>, "Fruit6", <invalid>, "Fruit4", <invalid>, "Fruit2", <invalid>, "Fruit0", <invalid> ]
    
        FruitSet.Shrink();
        // FruitSet == ["Fruit8", <invalid>, "Fruit6", <invalid>, "Fruit4", <invalid>, "Fruit2", <invalid>, "Fruit0" ]
    
    • 在上述代码中,Shrink 只删除了一个无效元素,因为末端只有一个空元素
  • 要移除所有slack,首先应调用 CompactCompactStable 函数,将空白空间组合在一起,为调用 Shrink 做好准备。
  • CompactStable 可在合并空元素时保持元素的排序
    FruitSet.CompactStable();
    // FruitSet == ["Fruit8", "Fruit6", "Fruit4", "Fruit2", "Fruit0", <invalid>, <invalid>, <invalid>, <invalid> ]
    FruitSet.Shrink();
    // FruitSet == ["Fruit8", "Fruit6", "Fruit4", "Fruit2", "Fruit0" ]
    

标签:TSet,TEXT,元素,Pear,C++,Orange,Grapefruit,UE5,FruitSet
From: https://www.cnblogs.com/scyrc/p/17498210.html

相关文章

  • UE5 C++ TMap
    概述映射的元素类型为键值对,元素类型实际上是TPair<KeyType,ElementType>,只将键用于存储和获取TMap和TMultiMap两者之间的不同点是TMap中的键是唯一的,而TMultiMap可存储多个相同的键TMap是散列容器,这意味着键类型必须支持GetTypeHash函数,并提供运算符==来比较各个键是否......
  • C++入门教程
    C++入门教程----------------------------------------------------------一.初识C++---------------------------------------------------------1.什么是C++.c++是一种较为基础的编程语言,虽然没有Python,Scratch那么高级,但是它应用范围很广.不论是信息奥赛还是国......
  • UE5 C++ TArray
    概述TArray是UE4中最常用的容器类。其速度快、内存消耗小、安全性高TArray类型由两大属性定义:元素类型和可选分配器元素类型是存储在数组中的对象类型。TArray被称为同质容器。换言之,其所有元素均完全为相同类型。单个TArray中不能存储不同类型的元素。分配器常被省略,默......
  • c++ doctest 测试报告
    地址https://github.com/laolang2016/doctest-reports效果未完成事项状态筛选没做只做了dashboard,其他两个页面还是空白四栏确实有点多了,数据应该纵向展示jquery果然还是比较墨迹,下一个版本使用vue......
  • Delete vector contents and free up memory in C++
     DeletevectorcontentsandfreeupmemoryinC++Thispostwilldiscusshowtodeletethevector’scontentsandfreeupthememoryallocatedbythevectortostoreobjectsinC++.1.Using vector::clear functionWecanusethe vector::clear......
  • visual studio 2022 c++ doxygen风格注释
    设置工具/选项/文本编辑器/C/C++/代码样式/常规注释效果输入/**添加注释鼠标停靠注释预览......
  • C++面试八股文:用过STL吗?
    某日二师兄参加XXX科技公司的C++工程师开发岗位第21面:面试官:用过STL吗?二师兄:(每天都用好吗。。)用过一些。面试官:你知道STL是什么?二师兄:STL是指标准模板库(StandardTemplateLibrary),是C++区别于C语言的特征之一。面试官:那你知道STL的六大部件是什么?二师兄:分别是容器(container......
  • C++面试八股文:了解auto关键字吗?
    C++面试八股文:了解auto关键字吗?某日二师兄参加XXX科技公司的C++工程师开发岗位第15面:面试官:了解auto关键字吗?二师兄:嗯,了解一些(我很熟悉)。面试官:说一说auto的用法吧?二师兄:auto主要是为了编译器进行类型推导。比如:autoi=42; //i被推导位int型std::vector<int>vi......
  • 现代C++学习指南-具体类
    类作为C++中重要的概念之一,有着众多的特性,也是最迷人的部分!类是一个加工厂,开发者使用C++提供的各种材料组装这个工厂,使得它可以生产出符合自己要求的数据,通过对工厂的改造,可以精细控制对象从出生到死亡的各种行为,真正达到我的代码我做主的境界。类我们经常说的面向对象三大特......
  • stringstream 与auto c++
    stringstream的用法,动态创建不同文件名for(inti=0;i<n;i++) { stringfilename; stringstreamss; ss<<"file"<<i<<".txt"; ss>>filename; ss.clear(); }auto的用法,通常用于for循环常规思路,我们想要输出一个数组的全部元素时,往往采用以下......