I'm using class templates together with the singleton model.
The code compiles, but I am an undefined reference linker error, on tB::getSingleton().
I've searched around on the internet and I've came a long way, but singletons in combination with a template class is not very common.
The code is as follows
A.h:
class A{
    public:
        // Constructor
        A() = default;
        // Destructor
        virtual ~A() = default;
        // Gets the singleton object
        template<class T>
        static std::shared_ptr<A>& getSingleton(){
            if (handle.get() == 0x0){
                std::shared_ptr<A> inst(new T());
                handle = std::move(inst);
            }
            return handle;
        }
    public:
        static std::shared_ptr<A> handle;
};
A_A.h:
#include <A.h>
class A_A : public A{
    public:
        // Constructor
        A_A() = default;
        // Destructor
        ~A_A(); // This is defined in the .cpp file
        static std::shared_ptr<A>& getSingleton()
        {
            if(A::handle.get() == nullptr){
                std::shared_ptr<A_A> inst(new A_A());
                A_A::handle = std::move(inst);
            }
            return A::handle;
        }
};
B.h:
template<typename A_Type>
class B{
    public:
        // Constructor
        B() = default;
        // Destructor
        virtual ~B() = default;
        /**
         * @brief Get the Singleton object
         *
         * @return B singleton instance
         */
        template<class T>
        static std::shared_ptr<B>& getSingleton(){
            if (handle.get() == 0x0){
                std::shared_ptr<B> inst(new T());
                handle = std::move(inst);
            }
            return handle;
        }
    public:
        static std::shared_ptr<B<A_Type>> handle;
};
B_B.h:
#include <A.h>
#include <B.h>
template <typename A_Type=A>
class B_B : public B<A_Type>{
    public:
    
        // Constructor
        B_B() = default;
        
        // Destructor
        ~B_B() = default;
        
        /**
         * @brief Get the Singleton object and sets the uart interface
         *
         * @return singleton instance
         */
        static std::shared_ptr<B<A_Type>>& getSingleton();
        
};
B_B.tpp:
#include <B.h>
#include <B_B.h>
template <typename A_Type>
std::shared_ptr<B<A_Type>> B<A_Type>::handle;
/**
 * @brief Get the Singleton object and sets the uart interface
 *
 * @return singleton instance
 */
template <typename A_Type>
std::shared_ptr<B<A_Type>>& B_B<A_Type>::getSingleton()
{
    if(B<A_Type>::handle.get() == nullptr){
        B<A_Type>::handle = std::move(std::static_pointer_cast<B<A_Type>>(new B_B<A_Type>()));
    }
    return B<A_Type>::handle;
}
C.h:
template<typename B_Type>
class C{
    public:
        // Constructor
        C() = default;
        // Destructor
        virtual ~C() = default;
        /**
         * @brief Get the Singleton object
         *
         * @return C singleton instance
         */
        template<class T>
        static std::shared_ptr<C>& getSingleton(){
            if (handle.get() == 0x0){
                std::shared_ptr<C> inst(new T());
                handle = std::move(inst);
            }
            return handle;
        }
    public:
        static std::shared_ptr<C<B_Type>> handle;
};
C_C.h:
#include <B.h>
template <typename B_Type=B>
class C_C : public C<B_Type>{
    public:
    
        // Constructor
        C_C() = default;
        
        // Destructor
        ~C_C() = default;
        
        /**
         * @brief Get the Singleton object and sets the uart interface
         *
         * @return singleton instance
         */
        static std::shared_ptr<C<B_Type>>& getSingleton();
        void doStuff();
        
};
C_C.tpp:
#include <B.h>
#include <B_B.h>
#include <C_C.h>
template <typename B_Type>
std::shared_ptr<C<B_Type>> C<A_Type>::handle;
/**
 * @brief Get the Singleton object and sets the uart interface
 *
 * @return singleton instance
 */
template <typename B_Type>
std::shared_ptr<C<B_Type>>& C_C<B_Type>::getSingleton()
{
    if(C<B_Type>::handle.get() == nullptr){
        C<B_Type>::handle = std::move(std::static_pointer_cast<C<B_Type>>(new C_C<B_Type>()));
    }
    return C<B_Type>::handle;
}
template <typename B_Type>
void C_C<B_Type> doStuff(){
  B_Type::getSingleton();
}
main.cpp:
#include <A.h>
#include <A_A.h>
#include <B.h>
#include <B_B.h>
using tB = B_B<A_A>;
using tC = C_C<tB>;
void main(){
  tC::getSingleton()->doStuff();
}
The compiler states the following:
error: no matching function for call to C<B<A> >::getSingleton()
