Why does adding a FString input make my function impossible to compile?

I’m hoping this is a tremendously obvious syntax burp on my part, but I’m setting up events in my HUD cpp so that I can hook functionality into those functions in blueprint. One of them simply needs to fire whenever an item is picked up, and provide the name of the item to my HUD so it can display a popup for the player:

UFUNCTION(Category = "Speech", BlueprintImplementableEvent)
void ItemPickupNotification(FString itemName);

This consistently produces an error, “error C2511: ‘void AHUDManager::ItemPickupNotification(const FString &)’: overloaded member function not found in ‘AHUDManager’”.

This sounds to me like there’s another function sharing this one’s name that the compiler thinks I’m trying to override, but I have verified that no function with the same name exists within the HUD class’s scope. Moreover, removing the argument and writing it like this allows it to compile perfectly:

UFUNCTION(Category = "Speech", BlueprintImplementableEvent)
void ItemPickupNotification();

So is there an obvious problem here? I’ve verified that changing the function’s name but leaving the FString argument produces the same error, so it can’t be a scope conflict, but I can’t figure out another reason why it would refuse to compile.

To me it seems like autogenerated blueprint bindings expect you to give a const-reference of string to the function, not a value.

Can you try changing the function declaration to:

UFUNCTION(Category = "Speech", BlueprintImplementableEvent)
void ItemPickupNotification(const FString& itemName);

And try if that works? Using a const-ref in this case is a typical C++ solution.
Yes, we have C++11 now and move semantics but with strings (especially std::string in other projects) it’s still probably better to just pass it by const-reference.

On a sidenote - if my theory is correct, I think this could be treated like a bug in UHT.

I found that changing the signature to the following makes it compile:

void ItemPickupNotification(const FString& itemName);

However, I’ll be darned as to why that works, which makes me hesitant to use it.

You’re absolutely right, this does resolve it… I wasn’t aware that passing strings by const-reference was a good idea in this context, but it definitely works; thank you! :slight_smile:

You’re welcome! That’s a good idea in general in C++ to pass complex objects as const-references btw :wink:

https://isocpp.org/wiki/faq/references#call-by-reference