ACharacter subclass in TSet: Cannot access private memberm

Hey guys,
I have a subclass of ACharacter named ABaseUnit. I want to save them in a TSet.
I’ve implemented the following functions (since they wont work I removed the functionality)

uint32 GetTypeHash(const ABaseUnit& A) {
	return 0;
}

bool operator== (const ABaseUnit& A, const ABaseUnit& B) {
	return true;
}

ABaseUnit does not contain any Private member (I removed them and put public direclty after GENERATED_BODY(). For testing I removed everythin from the class only leaving following code in the header of BaseUnit.

class PROJECT_API ABaseUnit : public ACharacter {
	GENERATED_BODY()
	
};

uint32 GetTypeHash(const ABaseUnit& A);

bool operator== (const ABaseUnit& A, const ABaseUnit& B);

The set is TSet SelectedUnits; but compilation throws following:

ABaseUnit::ABaseUnit cannot access private member declared in class ABaseUnit

I read somewhere that theres a code base with Examples for TSet, can anyone tell me where I can find that (The examples in the wiki only covers some basic stuff)

Hope I provided enought info and my tongue is not too bad.

class PROJECT_API ABaseUnit : public ACharacter {
GENERATED_BODY()

public:
     bool operator==(const ABaseUnit& Src) const
     {
         return //Compare
     }
 
     friend FORCEINLINE uint32 GetTypeHash(const ABaseUnit& Unit)
     {
         return //your Hash Function might want to use FCrc 
     }
}

If you dont want to overload you can make your own KeyFunc you can find a example in the TMap Doc:

Thanks for the repy. I tried that but it didn’t worked. Still getting that error.

You are using AHexMap* in my case I would use AHexMap without star. I’ve read if you use pointer in Sets you have to maintain memory, garrbage stuff by youself , but not if you use objects directly. Ithought it’s better to use the Objects.

And yes I know return true and 0 is nonsense, but it’s not the problem. I removed the logic there. :slight_smile:

Try again :stuck_out_tongue_winking_eye: from a pure Compiler standpoint it does not Complain (as you can see its running, not gonna use it atm since that true and 0 return is nonsense ^^)

Aside from that if you are on 4.15+ you dont need the operator and Hash implemantation it should be taken care of for you if Im not mistaken. Compiles fine and shows up correctly/works in BP.

Nope if you Flag it as UPROPERTY the Garbage Collection will be taken care for you. Aside from that UObject based non pointer types are not supported so you have to use * :stuck_out_tongue_winking_eye:

In that case the article I read is wrong and should be garbage collected XD.
Thank you, I will try that over the next week.

I just tried that and with pointers storred in Tset I allways get Accsess violaions as soon as I call the add function.

LoginId:1a54e1f3450b0a986ca1a18708c17132
EpicAccountId:8b911f0be0074b1687bf7e3cf444e1fd

Access violation - code c0000005 (first/second chance not available)

UE4Editor_Core!rml::internal::Block::findObjectSize()
UE4Editor_Core!FMallocTBB::Realloc() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\core\private\hal\malloctbb.cpp:82]
UE4Editor_Project_9244!TArray<TSparseArrayElementOrFreeListLink<TAlignedBytes<16,8> >,FDefaultAllocator>::ResizeGrow() [d:\work\own\unreal\epic games\engine\ue_4.16\engine\source\runtime\core\public\containers\array.h:2267]
UE4Editor_Project_9244!TSet<ABaseUnit * __ptr64,DefaultKeyFuncs<ABaseUnit * __ptr64,0>,FDefaultSetAllocator>::Emplace<ABaseUnit * __ptr64 const & __ptr64>() [d:\work\own\unreal\epic games\engine\ue_4.16\engine\source\runtime\core\public\containers\set.h:488]
UE4Editor_Project_9244!AStrategyPlayerController::AddSelectedUnit() [d:\work\own\unreal\projects\Project 4.16\source\Project\private\player\strategyplayercontroller.cpp:27]
UE4Editor_Project_9244!ABaseUnit::OnMouseClicked() [d:\work\own\unreal\projects\Project 4.16\source\Project\private\units\baseunit.cpp:94]
UE4Editor_Project_9244!ABaseUnit::execOnMouseClicked() [d:\work\own\unreal\projects\Project 4.16\source\Project\public\units\baseunit.h:20]
UE4Editor_CoreUObject!UFunction::Invoke() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\coreuobject\private\uobject\class.cpp:4461]
UE4Editor_CoreUObject!UObject::ProcessEvent() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\coreuobject\private\uobject\scriptcore.cpp:1313]
UE4Editor_Engine!AActor::ProcessEvent() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\engine\private\actor.cpp:689]
UE4Editor_Engine!TMulticastScriptDelegate<FWeakObjectPtr>::ProcessMulticastDelegate<UObject>() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\core\public\uobject\scriptdelegates.h:465]
UE4Editor_Engine!FActorOnClickedSignature_DelegateWrapper() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\engine\classes\gameframework\actor.h:48]
UE4Editor_Engine!FActorOnClickedSignature::Broadcast() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\engine\classes\gameframework\actor.h:48]
UE4Editor_Engine!UPrimitiveComponent::DispatchOnClicked() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\engine\private\components\primitivecomponent.cpp:3052]
UE4Editor_Engine!APlayerController::InputKey() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\engine\private\playercontroller.cpp:2167]
UE4Editor_Engine!UGameViewportClient::InputKey() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\engine\private\gameviewportclient.cpp:419]
UE4Editor_Engine!FSceneViewport::OnMouseButtonDown() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\engine\private\slate\sceneviewport.cpp:482]
UE4Editor_Slate!SViewport::OnMouseButtonDown() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\slate\private\widgets\sviewport.cpp:195]
UE4Editor_Slate!<lambda_ab77c21f1ddff5c8dfa7f5953c2a0e52>::operator()() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\slate\private\framework\application\slateapplication.cpp:4881]
UE4Editor_Slate!FEventRouter::Route<FReply,FEventRouter::FToLeafmostPolicy,FPointerEvent,<lambda_ab77c21f1ddff5c8dfa7f5953c2a0e52> >() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\slate\private\framework\application\slateapplication.cpp:239]
UE4Editor_Slate!FSlateApplication::ProcessMouseButtonDownEvent() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\slate\private\framework\application\slateapplication.cpp:4871]
UE4Editor_Slate!FSlateApplication::OnMouseDown() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\slate\private\framework\application\slateapplication.cpp:4816]
UE4Editor_Core!FWindowsApplication::ProcessDeferredMessage() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\core\private\windows\windowsapplication.cpp:1712]
UE4Editor_Core!FWindowsApplication::DeferMessage() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\core\private\windows\windowsapplication.cpp:2127]
UE4Editor_Core!FWindowsApplication::ProcessMessage() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\core\private\windows\windowsapplication.cpp:867]
UE4Editor_Core!FWindowsApplication::AppWndProc() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\core\private\windows\windowsapplication.cpp:714]
user32
user32
UE4Editor_Core!FWindowsPlatformMisc::PumpMessages() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\core\private\windows\windowsplatformmisc.cpp:1009]
UE4Editor!FEngineLoop::Tick() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\launch\private\launchengineloop.cpp:3058]
UE4Editor!GuardedMain() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\launch\private\launch.cpp:166]
UE4Editor!GuardedMainWrapper() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\launch\private\windows\launchwindows.cpp:134]
UE4Editor!WinMain() [d:\build\++ue4+release-4.16+compile\sync\engine\source\runtime\launch\private\windows\launchwindows.cpp:210]
UE4Editor!__scrt_common_main_seh() [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:264]
kernel32
ntdll

OKAY, now we get to the weird part:
I tried inserting normal FStrings like in Wiki but I also get access violations too. WTF is going on :-/

because this:

new ACharacter();

is not how you Spawn a Character into the World :stuck_out_tongue_winking_eye: the TSet is not your Problem here.

Example from a dummy Gamemode.

Everything works fine…

If you don´t mind at this Point Upload your Source (.h/.cpp) of the classes that are involved.

You know that you are still using the dummy GetTypeHash() and = operator override there? Aswell as the raw new Operator… why do expect it to work like that =/

Cleanup your Code!

Maybe I’m too stupid for this, can someone give me a basic example on how to add a ACharacter into a TSet

bool bAllreadyInSet;

ACharacter* a = new ACharacter();

TSet<ACharacter*> b;
b.Add(a, &bAllreadyInSet);

Why does this not work?

Okay, I read the article after I post this, that was just a test. In the real application the instance is allready there and tries to insert itself (over this referece) in the TSet which is located in the playercontroller.

Okay I see why my last post could not work, but not why the original stuff would not work.

Do I have to transform a this pointer somehow to insert it into a TSet? (ACharacter this reference (or in my case ABaseUnit))

Except that I have ABaseUnit instead of APlayerController I have the same setup.

https://pastebin.com/ivvfYCcZ

Must sound like a full noob.

It doesn’t work with or without them.And I removed the new operator, I accedently uploaded the wrong code. Its still there sry, will upload again.

Result:

Check for nullptr´s in your case. Somewhere something is not right on your side. Everything works as expected xD

https://pastebin.com/ivvfYCcZ

Clean code one link. But still as soon as I click on an ABaseUnit Actors I get Access violation when it gets inserted in the TSet.

But “this” cannot be a nullptr (I allready tried that but its impossible).