Download

no member named 'AsShared'

I have a line of code taken from the UT demo which is causing some rather esoteric errors during compiling which I don’t understand.

OnFindSessionCompleteDelegate.BindSP(this, &FMyServerBrowserUtils::OnFindSessionsComplete);

This line of code is spewing all sorts of errors. The last few lines are as follows:

/work/unreal/UnrealEngine/Engine/Source/Runtime/Core/Public/Delegates/DelegateSignatureImpl.inl(324,67) : error: no member named ‘AsShared’ in ‘FMyServerBrowserUtils’
return CreateSP( StaticCastSharedRef< UserClass >( InUserObject->AsShared() ), InFunc );

/work/unreal/UnrealEngine/Engine/Source/Runtime/Core/Public/Delegates/DelegateSignatureImpl.inl(790,10) : note: in instantiation of function template specialization ‘TBaseDelegate_OneParam<void, bool>::CreateSP<FMyServerBrowserUtils>’ requested here
*this = CreateSP( InUserObject, InFunc );

/home/redneck/Documents/Unreal Projects/MyGame/Source/MyGame/Private/MyServerBrowser.cpp(57,33) : note: in instantiation of function template specialization ‘TBaseDelegate_OneParam<void, bool>::BindSP<FMyServerBrowserUtils>’ requested here
OnFindSessionCompleteDelegate.BindSP(this, &FMyServerBrowserUtils::OnFindSessionsComplete);

What’s broken?

BindSP is really a shortcut for CreateSP, where the SP stands for shared pointer. In order to obtain a shared pointer, you normally have to call MakeShareable, i.e.:



TSharedPtr<FMyServerBrowserUtils> BrowserUtils = MakeShareable( new FMyServerBrowserUtils() );


That’s the nitty gritty details. You could manually create a delegate in this fashion and assign it to OnFindSessionCompleteDelegate. But that’d be troublesome, especially since you’re already in the class and you don’t really care how it is being referenced by the delegate.

Thankfully, UE4 provides a handy little construct to avoid having to manually create shared pointer delegates. This is the “AsShared” function that’s being called by the BindSP shortcut. In order for your class to have this, it first needs to inherit from TSharedFromThis, like so:


class FMyServerBrowserUtils : public TSharedFromThis<FMyServerBrowserUtils>

The template syntax might seem a bit weird, but it allows automagically adding to your class a “AsShared” function that returns a TSharedPtr<FMyServerBrowserUtils>. Then BindSP will happily use that shared pointer to create a delegate.

-Camille

Hmmm. This is a problem. The troublesome call is occuring inside one of the class methods. There’s no pointer inside the method (other than ‘this’) because the class hasn’t been instantiated yet. I’m guessing that the delegates will need to be assigned after the class is instantiated. Correct?

You can ignore my explanation of shared pointers if it wasn’t clear, I was just trying to provide some context to the nature of TSharedPtrs. But that’d require more than a few lines.

All you should need to do is add the inherited “public TSharedFromThis<FMyServerBrowserUtils>” to your class and that’ll take care of it.

Sorry, no go.

“static_assert((!CanConvertPointerFromTo<ObjectType, UObjectBase>::Result), “You cannot use TSharedRef with UObjects.”);”

Shared pointer only work on non-uobjects. UObjects are garbage collected, so thet don’t really need smart pointers.

If you want to use smart pointer with UObject you use TWeakObjectPtr<>

1 Like

Ah, going on the F prefix to FMyServerBrowserUtils, I had assumed it wasn’t a UObject. That convention is there for a reason. :slight_smile:

If it’s a UObject, you should use BindUObject instead:


OnFindSessionCompleteDelegate.BindUObject (this, &FMyServerBrowserUtils::OnFindSessionsComplete);

Though I’m surprised it didn’t carp out saying you can’t use BindSP on UObjects, I recall there was a warning for that.

I wanted to post this yesterday but was getting database errors. But there you go.

1 Like

Hooray! The BindUObject fixed part of the problem. But there one more still in there. I’m assuming it’s the same problem. But google won’t tell me what it needs to be changed to:

Beacon->OnServerRequestResults = FServerRequestResultsDelegate::CreateSP(this, &UMyServerBrowser::OnServerBeaconResult );

The error is “error: no member named ‘AsShared’ in ‘UMyServerBrowser’”

FYI: The big picture here is that this class is the parent class to a UMG blueprint. It’s derived from UUserWidget.

That’s the longhand CreateSP delegate form I mentioned earlier. Same problem, similar solutions:


Beacon->OnServerRequestResults = FServerRequestResultsDelegate::CreateUObject(this, &UMyServerBrowser::OnServerBeaconResult );

Or, the same Bind shortcut should work:


Beacon->OnServerRequestResults.BindUObject( this, &UMyServerBrowser::OnServerBeaconResult );

There are a few different ways to bind to delegates, BindRaw, BindStatic, BindSP, BindUObject (and, in 4.6, BindLambda). They’re all described in Delegate.h if you wish to learn more about them.

Yep, I rooted thru the underlying code and found the CreateUObject function. That fixed it.

BTW: There’s some documentation on this stuff hiding in the Core module files:

Runtime/Core/Public/Delegates/DelegateSignatureImpl.inl