How to pass function pointer while calling a template method that has class and function pointer as template parameters

This is the method that I have created:

template <typename T>
void UEventSystemManager::SubscribeToEvent(const FName EventName, T *testGame, void (T::*func) ())
{
    FTestEventDelegate* EventDelegate = EventDelegates.Find(EventName);
    EventDelegate->AddUniqueDynamic(testGame, func);
}

I am trying to call it in a different class constructor like below:

ATestGameElement::ATestGameElement()
{
	UEventSystemManager* EventManager = UEventSystemManager::GetInstance();
	EventManager->SubscribeToEvent("TestFiringEvent",this, &ATestGameElement::HandleEvent);
}

This is my HandleEvent:

void ATestGameElement::HandleEvent()
{
	// Handle the event here
	UE_LOG(LogTemp, Warning, TEXT("Event handled by UTestGameElement"));
	GEngine->AddOnScreenDebugMessage(-1, 10.0, FColor::Green, TEXT("Success"));
}

This is throwing me error LNK2019 unresolved external symbol error. I am unable to resolve it its been 2 days. I need help

Full code:
TestGameElement.cpp

#include "TestGameElement.h"

#include "EventSystemManager.h"

#include <functional>

#include "EventDispatcher.h"

void ATestGameElement::HandleEvent()
{
	// Handle the event here
	UE_LOG(LogTemp, Warning, TEXT("Event handled by UTestGameElement"));
	GEngine->AddOnScreenDebugMessage(-1, 10.0, FColor::Green, TEXT("Success"));
}

void ATestGameElement::TestEvent()
{
	// Handle the event here
	UE_LOG(LogTemp, Warning, TEXT("Event handled by UTestGameElement"));
	GEngine->AddOnScreenDebugMessage(-1, 10.0, FColor::Green, TEXT("Success"));
}


ATestGameElement::ATestGameElement()
{
	UEventSystemManager* EventManager = UEventSystemManager::GetInstance();
	GEngine->AddOnScreenDebugMessage(-1, 10.0, FColor::Green, TEXT("Test Game Element Initialized"));
	EventManager->RegisterEvent("Teeeeeest");
	auto callback = [this](){
		HandleEvent();
	};
	//void (ATestGameElement::*func) = TestEvent();
	EventManager->SubscribeToEvent("TestFiringEvent",this, &ATestGameElement::HandleEvent);
}




EventSystemManager.cpp

#include "EventSystemManager.h"

UEventSystemManager* UEventSystemManager::Instance = nullptr;

UEventSystemManager::UEventSystemManager()
{
    if (Instance == nullptr)
    {
        Instance = this;
    }
}

UEventSystemManager* UEventSystemManager::GetInstance()
{
    return Instance;
}

void UEventSystemManager::RegisterEvent(const FName EventName)
{
    GEngine->AddOnScreenDebugMessage(-1, 10.0, FColor::Green, TEXT("Registered event"));
    EventDelegates.Add(EventName, FTestEventDelegate());
}

//void (T::*func)
template <typename T>
void UEventSystemManager::SubscribeToEvent(const FName EventName, T *testGame, void (T::*func) ())
{
    FTestEventDelegate* EventDelegate = EventDelegates.Find(EventName);
    
    EventDelegate->AddUniqueDynamic(testGame, func);
    
}
    

This is the exact error message:
TestGameElement.cpp.obj : error LNK2019: unresolved external symbol “public: void __cdecl UEventSystemManager::SubscribeToEvent(class FName,class ATestGameElement ,void (__cdecl ATestGameElement::)(void))”

: fatal error LNK1120: 1 unresolved externals

What is the actual error message?

You need to post more code, from what you have posted its impossible to tell if all this code is in the same module or whether the template definition is in a .cpp or .h file, both of which are relevant to solving the problem

Hi, I have edited the post with full code and exact error message. Please take a look if possible. Thanks

Templates must be implemented in header files, otherwise when trying to use it from a different module, there is a high chance that specific instantiation doesn’t exist in the implementing module.

Thanks for the suggestion! I have moved the implementation to header file. But now when I compile the solution, unreal is crashing with the below error message:
Assertion failed: Result && Result[2] != (TCHAR)‘0’ [File:D:\UE_5.2\Engine\Source\Runtime\Core\Public\Delegates\Delegate.h] [Line: 475] ‘func’ does not look like a member function

AddUniqueDynamic is a macro that works by function name, you cannot give it a variable.

The way dynamic delegates work internally also require the name of the function, to be able to detect blueprint implementations, so you have to pass the name of the function to your subscribe template.

Then you can call the internal function rather than the macro :

EventDelegate->__Internal_AddUniqueDynamic(testGame, func, funcName);

//usage:
EventManager->SubscribeToEvent("TestFiringEvent", this, &ATestGameElement::HandleEvent, "HandleEvent");

If you want simpler usage you have to mimic what UE4 does, wrap your template with a macro to extract function name from passed in function pointer.
Something like this :

template<typename T>
void UEventSystemManager::__SubscribeToEvent(const FName& EventName, T* Obj, void (T::*Func)(), const FName& FuncName)
{
    FTestEventDelegate* EventDelegate = EventDelegates.Find(EventName);
    EventDelegate->__Internal_AddUniqueDynamic(Obj, Func, FuncName);
}

#define SubscribeToEvent(EventName, Obj, Func) __SubscribeToEvent(EventName, Obj, Func, STATIC_FUNCTION_FNAME(TEXT(#Func)))

I have made the changes as suggested. Currently my code looks like this:

EventSystemManager.h

template<typename T>
	void SubscribeToEvent(const FName& EventName, T* Obj, void (T::*Func)(), const FName& FuncName)
	{
		FTestEventDelegate* EventDelegate = EventDelegates.Find(EventName);
		EventDelegate->__Internal_AddUniqueDynamic(Obj, Func, FuncName);
	}

TestGameElement.cpp

ATestGameElement::ATestGameElement()
{
	UEventSystemManager* EventManager = UEventSystemManager::GetInstance();
EventManager->SubscribeToEvent("TestFiringEvent", this, &ATestGameElement::HandleEvent, "HandleEvent");
}

When I compile now, unreal crashes with the below error:

Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x0000000000000000

UnrealEditor_GAME_0001!TArray<TScriptDelegate,TSizedDefaultAllocator<32> >::Find() [D:\UE_5.2\Engine\Source\Runtime\Core\Public\Containers\Array.h:949]
UnrealEditor_GAME_0001!TArray<TScriptDelegate,TSizedDefaultAllocator<32> >::AddUniqueImpl<TScriptDelegate const &>() [D:\UE_5.2\Engine\Source\Runtime\Core\Public\Containers\Array.h:2433]
UnrealEditor_GAME_0001!TBaseDynamicMulticastDelegate<FWeakObjectPtr,void>::__Internal_AddUniqueDynamic() [D:\UE_5.2\Engine\Source\Runtime\Core\Public\Delegates\DelegateSignatureImpl.inl:1173]
UnrealEditor_GAME_0001!ATestGameElement::ATestGameElement() [E:\XX\Private\TestGameElement.cpp:37]
UnrealEditor_CoreUObject
UnrealEditor_CoreUObject

Constructor is probably not a good place to grab the EventManager as it might not exist yet.
Try BeginPlay instead.