Download

Convert TArray<? extends CoolClass> into TArray<CoolClass>

You see, I have this class “FStringSerializable” that contains exactly one method:

public abstract FString ToString();

From there, I have a lot of classes implementing this, and with this method they can all be printed into the console easily.

The goal is this:

public:
  /**
    *  This method takes a list of elements and returns one FString with
    *  all of them converted into text, separated by a separator (usually a comma).
    */
  static FString Concatenate(TArray<FStringSerializable*> Elements, char Separator);

But all TArrays I’ll ever have is of things that implement FStringSerializable, for example, ‘FDouble’ which is just a wrapper for double that implements FStringSerializable.

Thus I have a TArray<FDouble*> that can’t be passed as a TArray<FStringSerializable*>.

I guess I can always use a for loop and copy the contents from the FDouble array to the other array, but what about when I have FBool, or FInt? How to, in general, transform an array of ‘? extends StringSerializable’ to ‘StringSerializable’?

Thought to make a function that takes the TArray<FDouble*>.CreateIterator() and just blindly casts the elements into FStringSerializable*

TArray<FStringSerializable*> FStringStuff::Rearrange(const TIterator& StringSerializables) {

	// Create result array
	TArray<FStringSerializable*> Ret;

	// Iterate through all of those things
	for (auto Element = StringSerializables; Element; ++Element) {

		// Well it seems this is the syntax
		FPreviewAttachedObjectPair Preview = *Element;

		// Convert that address into a Pointer to a FStringSerializable*
		FStringSerializable** Converted = reinterpret_cast<FStringSerializable**>(&Preview);

		// Add the value of that converted thing
		Ret.Add(*Converted);
	}

	// Yes
	return Ret;
}

But then I have this weird compiler error ‘Cannot convert rvalue of type TArray<FMetaObject>::TIterator to parameter type const TIterator*’:

  // Turn all the doubles into a comma separated list
  FString Result = FStringStuff::Concatenate(FStringStuff::Rearrange(GDoubles.CreateIterator()), ',');

Concatenate Method:

FString FStringStuff::Concatenate(TArray<FStringSerializable*> Elements, char Separator) {

	// String builder
	FString Result = "";

	// Straight up, through all the elements
	int Size = Elements.Num();
	bool SkipSeparator = true;
	for (int i = 0; i < Size; i++) {

		// Valid Entry?
		FStringSerializable* ObjectPtr = Elements[i];
		if (ObjectPtr == nullptr) { continue; }

		// Append Separator before the element, except for the very first element.
		if (!SkipSeparator) { Result += Separator; } else { SkipSeparator = false; }

		// Append value of the element
		Result += (*ObjectPtr).ToString();
	}

	// Return that
	return Result;
}

It should be possible to do something like this. This also saves you from essentially having to create a second copy of the array.
TArrayView<FStringSerializable*> Whatever = MakeArrayView<FStringSerializable*>(reinterpret_cast<FStringSerializable**>(GDoubles.GetData()), GDoubles.Num());