[4.6.1] Returning reference to structure gives error

I am trying to return a reference to a structure which can be called by blueprints. I can get it to compile in c++, but in blueprints, I get an error “Error The direction of Return Value doesn’t match the direction of parameter ReturnValue”.

Here’s my definition:

USTRUCT( BlueprintType )
struct FRaptorActivateTask
{
...
};


UFUNCTION( BlueprintCallable, Category = RaptorInteractive )
const struct FRaptorActivateTask& GetInteractTask( ERaptorInteractType::Type InteractTaskType ) const;

I only get the blueprint error when the node is fully connected to a exec chain.

I noticed a similar definition in UPrimitiveComponent:

USTRUCT(BlueprintType)
struct FWalkableSlopeOverride
{
...
};

UFUNCTION(BlueprintCallable, Category="Physics")
const struct FWalkableSlopeOverride& GetWalkableSlopeOverride() const;

This gives the exact same blueprint compile error.

So, either my class and UPrimitiveComponent are doing it wrong, or the compiler is doing something wrong.

Please advise.

Hi ,

Thank you for pointing this out to us. I ran some tests and was able to see the results that you described. I have entered a report to have this investigated further (UE-8693).

This bug is also present in 4.7 preview.

Ok, found my mistake.

Of course you can’t set any value of the struct if it’s const. Just remove the const keyword, and it should work!

Yes! That was it. I glossed over my “const” as well. Making non-const removed the error. I guess what would be helpful is to change the error to something like “can’t set value on const reference”.

hey mate, i asked a similar question. This is what happens when you try to return a const reference via “normal” c++ way.

You can return a reference via the C way using it as an OutParam.

here is the link to my question.

however i havnt figured how to return it as const

This still does not explain to me why it is impossible to return such a value as const. If you don’t want to alter the returned value, it should be const

Hi Wallenstein,

Blueprints don’t actually know what const means, so if this is only being used in Blueprints, the const keyword doesn’t help much. What I did find that worked in this case is instead of using const struct FTestStruct& AMyActor::GetTestStruct() const, use const struct FTestStruct AMyActor::GetTestStruct() const instead. Leaving the & out seems to allow this to work as expected.

While this may work, it shouldn’t be this way. You should be able to return a const reference from a function. If the blueprint system then chooses to copy this into a new non-const/ref structure, so be it, the inefficiencies of BP climb.

The problem lies here:

		const bool bOutParam = (Property->HasAnyPropertyFlags(CPF_OutParm | CPF_ReturnParm) && !(Property->HasAnyPropertyFlags(CPF_ReferenceParm)));

		if ( ((SourcePin->Direction == EGPD_Input) && bOutParam) || ((SourcePin->Direction == EGPD_Output) && !bOutParam))
		{
			MessageLog.Error(*FString::Printf(*LOCTEXT("DirectionMismatchParameter_Error", "The direction of @@ doesn't match the direction of parameter %s").ToString(), *Property->GetName()), SourcePin);
		}

An an out param (i.e. return value) cannot be a reference, const or not, which is entirely silly.

Hi TTaM,

You are correct that you will receive an error message when trying to have a reference as a return value (as in the original post, for example). This is unfortunately a current limitation of Blueprints.

However, you are still able to pass parameters to a BlueprintCallable function as references, and those should function normally. There is one thing to keep in mind, however. If you write your function declaration like you normally would in C++, the parameter will appear on the node as an output pin instead of as an input pin. For example, the following code will give you a Return Float output pin:

UFUNCTION(BlueprintCallable, Category = TestCat)
void TestFunc(float& ReturnFloat);

However, if you add UPARAM(ref) before the parameter, it will instead appear as an input pin:

UFUNCTION(BlueprintCallable, Category = TestCat)
void TestFunc(UPARAM(ref) float& ReturnFloat);

You can also make the parameters that are references const if you wish.