TSet: Sets in C++
TSet is another type of container similar to TArray. Conceptually, a Set is an unordered list of unique elements. The TSet template has a parameter to allow duplicate elements and also has a function for sorting, but in this article, we will focus on the traditional use of a Set.
A TSet does not use an index. The element’s value is used as the key. The elements of a TSet must be of the same type.
The example below creates a TSet with the name CreaturesByRegion to store elements of type FString. This TSet can be modified in the editor.
UPROPERTY(EditAnywhere, Category=SetExample)
TSet<FString> CreaturesByRegion;
Use the Add() function to add elements to a TSet in C++.
CreaturesByRegion.Add(TEXT("Ghoul"));
CreaturesByRegion.Add(TEXT("Necrophage"));
CreaturesByRegion.Add(TEXT("Werewolf"));
To see how many elements there are in a TSet, use the Num() function:
int32 NumberOfElements = CreaturesByRegion.Num();
Use the Contains() function to check if an element is part of a TSet:
bool bHasCreature = CreaturesByRegion.Contains(TEXT("Necrophage"));
To remove an element, use the Remove() function. If the element is not found, the function returns a value of 0.
int32 RemovedAmount = CreaturesByRegion.Remove(TEXT("Ghoul"));
To remove all items from a TSet, use the Empty() function:
CreaturesByRegion.Empty();
TSet has some functions that perform operations with two Sets and return a different Set. These are the functions:
- Union(): Returns a TSet containing the elements of the two Sets. Duplicates will be removed.
- Difference(): Returns a TSet that contains the elements of the first Set that are not in the second Set.
- Intersect(): Returns a TSet containing only the elements that exist in the two Sets.
The code below shows the use of these functions.
TSet<int32> Set1;
TSet<int32> Set2;
Set1.Add( 3 );
Set1.Add( 5 );
Set1.Add( 7 );
Set2.Add( 4 );
Set2.Add( 5 );
Set2.Add( 6 );
TSet<int32> UnionResult = Set1.Union(Set2);
// UnionResult = [ 3, 4, 5, 6, 7 ]
TSet<int32> DifferenceResult = Set1.Difference(Set2);
// DifferenceResult = [ 3, 7 ]
TSet<int32> IntersectResult = Set1.Intersect(Set2);
// IntersectResult = [ 5 ]
Example usage:
Create a C++ class with the name TestTSet using the Actor class as the parent class. In the TestTSet.h file, add the declaration of the components and of the TSet:
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "TestTSet.generated.h"
UCLASS()
class TUTOPROJECT_API ATestTSet : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ATestTSet();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UPROPERTY(VisibleAnywhere)
USceneComponent* RootScene;
UPROPERTY(VisibleAnywhere)
UStaticMeshComponent* StaticMesh;
UPROPERTY(EditAnywhere, Category=SetExample)
TSet<FString> CreaturesByRegion;
};
In the BeginPlay() function, we will write on the screen the name of the TSet elements. A ranged-based for loop is used to iterate over the TSet elements. The contents of the TestTSet.cpp file look like this:
#include "TestTSet.h"
ATestTSet::ATestTSet()
{
// Set this actor to call Tick() every frame.
PrimaryActorTick.bCanEverTick = true;
RootScene = CreateDefaultSubobject<USceneComponent>("RootScene");
RootComponent = RootScene;
StaticMesh = CreateDefaultSubobject<UStaticMeshComponent>("StaticMesh");
StaticMesh->SetupAttachment(RootScene);
}
// Called when the game starts or when spawned
void ATestTSet::BeginPlay()
{
Super::BeginPlay();
FString Message;
if(CreaturesByRegion.Num() > 0)
{
Message = FString::Printf(TEXT("Number of elements in the Set: %d"),
CreaturesByRegion.Num());
if(GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Red, Message);
for (FString Creature : CreaturesByRegion)
{
Message = FString::Printf(TEXT("Creature Name: %s"), *Creature);
GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Red, Message);
}
}
}
}
// Called every frame
void ATestTSet::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
Compile the C++ code and add an instance of TestTSet at the level. You can add elements in the TSet using the Details tab of the instance. Try adding a duplicate value. A message will appear saying that it is not allowed.
Start the game and see on the screen the names of the elements added to the TSet: