TMap<TObjectPtr<>> Conversion Problem

I’m in the process of updating all UPROPERTY() pointer references to use TObjectPtr<> and I’ve ran into a seemingly simple issue I’m not quiet sure how to resolve.

I have the following UFUNCTION:

UFUNCTION()
TSet<UDispatcher*>& GetRegisteredDispatchers() { return RegisteredDispatchers; }

It’s supposed to return a reference to:

UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
TSet<TObjectPtr<UDispatcher>> RegisteredDispatchers;

but somehow I can’t seem to be able to convert TSet<TObjectPtr> to TSet<UDispatcher*>. Any ideas?

I tried a cast with:

static_cast<TSet<UDispatcher*>&>(RegisteredDispatchers);

but that also doesn’t work. I know the cast works for TArrays, but apparently not TMaps.

try:

UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
TSet<TObjectPtr<UDispatcher>> RegisteredDispatchers;

 FORCEINLINE TSet<TObjectPtr<UDispatcher>>& GetRegisteredDispatchers() { return RegisteredDispatchers; }

Exposing it with the UFUNCTION macro is what is causing the error.

Thank you @3dRaven , would you happen to know if it’s possible to have it somehow converted so I can keep the UFUNCTION macro?

This was a simplified example but there’s cases where I need to convert from:

TSet<TObjectPtr<UDispatcher>> 

to

TSet<UDispatcher*>&

in UFUNCTIONs.

Not a 100% sure but I think it has to due with how unreal handles reflections.

It’s an optional lazy load object so it has it’s own life cycle. If you’d expose it to blueprints via the UFUNCTION macro then I think that collides with the blueprints life cycle.

It’s an ongoing problem that you can see pops up from time to time on the forum. I hope Epic final addresses it in the future.

Edit:
Perhaps using TSoftObjectPtr and manual resolving it upon request inside of the return function could be an option

Thank you again. I ended up converting the TSet to a TArray for now… will have to revisit it at some point :neutral_face:

Maybe GPT 4o can solve it :face_with_raised_eyebrow:

You can use this:

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
	TSet<TObjectPtr<UObject>> RegisteredDispatchers;
	
	UFUNCTION()
	TSet<UObject*>& GetRegisteredDispatchers() { return MutableView(RegisteredDispatchers); }

There are a suite of functions ObjectPtrDecay and ObjectPtrWrap that can do this conversion so:

UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
TSet<TObjectPtr<UObject>> RegisteredDispatchers;
	
UFUNCTION()
TSet<UObject*>& GetRegisteredDispatchers() { return ObjectPtrDecay(RegisteredDispatchers); }

Is what you want.