Hello the community,
I have a very specific question and I don’t find any anwsers on the Doc or on forums.
It happened to me to use the spread operator from other languages, and I see that in c++ there is it’s equivalent with the Parameter Pack (a.k.a T…) and I’m wondering if it’s viable with the Unreal API.
I’ve read that it has been introduced in the c++11 and from an old post that the compiler of Unreal is at least c++11. So I give it a try.
I was trying to create a ‘Terminal like’ where I could enter some commands and trigger functions with arguments.
I store in a TMap the functions names as keys and the delegates to the functions as values.
Then, at BeginPlay I hardcode all my delegates, their bindings, and add them to the map with their particular keys.
And everything is working fine for that.
But then, when I receive an input from my player, I check if the function he want to execute is contained in my Map, then retrieve the delegate. But when I try to execute it, it says that he “cannot convert rvalue of type ‘FString’ to type ‘FString…’”. And when I enter two args it says “Function has 1 parameter, but is called with 2”.
So, is the Parameter pack not good to use with Unreal ?
Maybe it’s just the Delegates that don’t support it for their call.
If not, does someone would have a good workaround ?
I could use a TArray of args, but it is not as clean.
Terminal.h
TMap<const FString, TBaseDelegate<void, const FString...>> Actions;
void ActionOpen(const FString... Args);
void ActionClose(const FString... Args);
virtual void CallAction_Implementation(const FString &FunctionName, const FString&... Args) override;
Terminal.cpp
void ATerminal::BeginPlay()
{
Super::BeginPlay();
TBaseDelegate<void, const FString...> OpenDelegate;
OpenDelegate.BindUObject(this, &ATerminal::ActionOpen);
this->Actions.Add(TEXT("Open"), OpenDelegate);
TBaseDelegate<void, const FString...> CloseDelegate;
CloseDelegate.BindUObject(this, &ATerminal::ActionClose);
this->Actions.Add(TEXT("Close"), CloseDelegate);
}
void ATerminal::CallAction_Implementation(const FString &FunctionName, const FString&... Args)
{
UE_LOG(LogTemp, Warning, TEXT("CallAction called"));
if (this->Actions.Contains(FunctionName))
{
UE_LOG(LogTemp, Warning, TEXT("[%s] Call %s action"), *this->GetName(), *FunctionName);
this->Actions[FunctionName].ExecuteIfBound(Args); // Error here : cannot convert rvalue of type 'const FString' to type 'const FString...'
}
else
{
UE_LOG(LogTemp, Error, TEXT("no function found"));
}
}
Thank you for reading and for sharing info.