Download

Only one Custom Struct, out of all require "==" operator overload to work with TArray

[FONT=Arial Black](EDIT: I found the answer. I was using AddUnique when adding structs to the array, so it would need a way to compare and see if it was already existing in the array, therefore the need for the operator.)


USTRUCT(BlueprintType)
 struct FPaperSkeletonSkinData
 {
     GENERATED_USTRUCT_BODY()
 
     UPROPERTY(EditAnywhere, BlueprintReadOnly)
     FName SlotName;
 
     UPROPERTY(EditAnywhere, BlueprintReadOnly)
     FName NonSpecificName;
 
     class UPaperSkeletonAttachment* Attachment;
 
     FPaperSkeletonSkinData(){}
 
     FPaperSkeletonSkinData(FName slotName, FName nonSpecificName, class UPaperSkeletonAttachment* attachment)
         : SlotName(slotName), NonSpecificName(nonSpecificName), Attachment(attachment)
     {
     }
 
     bool operator==(const FPaperSkeletonSkinData& rightSkin) const;
 };


 UPROPERTY(EditAnywhere, BlueprintReadOnly)
 TArray<FPaperSkeletonSkinData> Attachments;

Above is the Custom Struct that required a “==” operator be set, so that TArray’s.Find function could work properly. My question is, why does this Custom Struct require that, when the other Custom Struct below, which is stored in a TArray aswell, doesn’t require the “==” operator overload even though its almost 2-3 times as complicated.

(NOTE: I’m never actually explicitly using the TArray.Find function, only using for-each loops)


USTRUCT(BlueprintType)
 struct FPaperSkeletonAnimationData
 {
     GENERATED_USTRUCT_BODY()
 
     // Skeleton Data (Owner)
     class UPaperSkeletonData* Owner;
 
     // Name of the Animation
     UPROPERTY(EditAnywhere)
     FName AnimationName;
 
     // Duration of the Animation
     UPROPERTY(EditAnywhere)
     float Duration;
 
     // Should the animation loop?
     UPROPERTY(EditAnywhere)
     bool bShouldLoop;
 
     // Timelines/Objects relative to the Animation
     UPROPERTY(EditAnywhere)
     TArray<FPaperSkeletonTimelineData> Timelines;
 
     FPaperSkeletonAnimationData(){}
 
     FPaperSkeletonAnimationData(class UPaperSkeletonData* owner, FName animationName, float duration, bool shouldLoop, TArray<FPaperSkeletonTimelineData>& timelines)
         : Owner(owner), AnimationName(animationName), Duration(duration), bShouldLoop(shouldLoop), Timelines(timelines)
     {
     }
 
     FPaperSkeletonTimelineData* FindTimeline(FName objectName);
 
 };


     // Skeleton Animations
     UPROPERTY(EditAnywhere, BlueprintReadOnly)
     TArray<FPaperSkeletonAnimationData> Animations;

(AnswerHub Reference - Only Certain Custom Structs Require “==” Operator for TArray’s to work)

calling TArray::AddUnique will call TAarray::AddUniqueImpl which will call TArray::Find



template <typename ArgsType>
int32 AddUniqueImpl( ArgsType&& Args )
{
	int32 Index;
	if (Find(Args, Index))
		return Index;

	return Add(Forward<ArgsType>(Args));
}
...]

int32 Find( const ElementType& Item ) const
{
	const ElementType* RESTRICT Start = GetTypedData();
	for (const ElementType* RESTRICT Data = Start, * RESTRICT DataEnd = Data + ArrayNum; Data != DataEnd; ++Data)
	{
		if (*Data == Item)
			return (int32)(Data - Start);
	}
	return INDEX_NONE;
}


Any class/struct that is to be used in functions the actually use the comparison operator of the objects will fail to compile if the comparison operator has not been explicitly defined, as there is no default definition of that operator in c++:

Which means: If you use a class in a TArray in some way that needs to access the comparison operator, you will have to implement said operator in your class/struct.