Download

How to forward declare a template class in a header file

Hi, Im trying to figure out how to forward declare a template class in a header file, so that I don’t have to mess around with includes in the header.

Here is the template class(s) - a simple FSM.



// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"

template<class T> class C_FSMState
{
public:
    T &Owner = NULL;
    int ID = -1;

    template <typename T>
    void Register(int id, T &owner) : Owner(owner), ID(id) { }
    virtual void Init() = 0;
    virtual void Tick(float deltaTime) = 0;
    virtual void Exit() = 0;

    virtual ~C_FSMState() = 0;
};

template<class T> class EJL_API C_FSM
{
public:
    T* Owner = NULL;
    FString Name;

    template <typename T>
    C_FSM(T* owner, FString name, bool showDebug = false)
    {
        Owner = owner;
        Name = name;
        _container = TMap<int, C_FSMState<T>*>();
        _state = NULL;
        _showDebug = showDebug;

        Debug(FString::Printf(TEXT("Created a new FSM: %s"), *name));
    }

    template <typename T>
    void AddState(int id, C_FSMState<T>* state, bool overwrite = false)
    {
        if (id < 0)
        {
            Debug(FString::Printf(TEXT("Cannot add a state with a negative ID!")));
            return;
        }

        if (!state)
        {
            Debug(FString::Printf(TEXT("A null pointer was passed in for as the state. Don't do that!")));
            return;
        }

        if (_container.Contains(id))
        {
            if (overwrite)
            {
                delete _container[id];
                _container[id] = state;
            }
            else
            {
                Debug(FString::Printf(TEXT("A state with id %d] already exists in this FSM. You can set 'replace' to true, to overwrite it"), id));
            }
        }
        else
        {
            _container.Add(id, state);
        }
    }

    void Test()
    {
        Debug(FString("TEST"));
    }

    void Switch(int state)
    {

    }

    void Tick(float deltaTime)
    {

    }

    ~C_FSM()
    {
        // Deallocate memory and clear container. Don't call delete on player pointer, just delete the variable.
    }

private:
    class TMap<int, C_FSMState<T>*> _container;
    C_FSMState<T>* _state;
    bool _showDebug;

    void Debug(FString msg)
    {
        if (_showDebug)
        {
            UE_LOG(LogTemp, Warning, TEXT("%s"), *msg);
        }
    }
};


I have tried these so far:



    template<class T> class C_FSM<AC_Enemy> _fsm;




    template <class T>
    class C_FSM<AC_Enemy> _fsm;




    class C_FSM<AC_Enemy> _fsm;




    class C_FSM<AC_Enemy>* _fsm;


I’m sure I’m probably severely misunderstanding how templates are meant to work, but I’ve only just started using them so any help is appreciated!

J