0

I encountered the following linker errors and I can't seem to find out why Observable<T> doesn't get defined:

CMakeFiles/Sapling.dir/Core/Window/SdlWindow.cpp.o: In function `se::SdlWindow::SdlWindow(se::Window::State const&)':
/home/glados/ClionProjects/Sapling/Core/Window/SdlWindow.cpp:9: undefined reference to `se::Observable<se::WindowEvent>::addObserver(se::Observer<se::WindowEvent>*)'
CMakeFiles/Sapling.dir/IO/SdlInput.cpp.o: In function `se::SdlInput::processEvent(SDL_Event const&)':
/home/glados/ClionProjects/Sapling/IO/SdlInput.cpp:83: undefined reference to `se::Observable<se::WindowEvent>::notify(se::WindowEvent const&)'
collect2: error: ld returned 1 exit status

The problem seems to be about these two classes:

Observer.h

#ifndef OBSERVER_H
#define OBSERVER_H

#include "../Util/UID.h"

namespace se {

    template <typename T>
    class Observer {

    public:

        Observer();
        virtual ~Observer() { }

        virtual void onNotify(const T& subject) = 0;

        const UID& getId() {
            return m_id;
        }

    private:
        UID m_id;
        static UIDPool m_uidPool;
    };

} // namespace se
#endif

Observer.cpp

#include "Observer.h"

namespace se {

    template <typename T>
    UIDPool Observer<T>::m_uidPool = UIDPool();

    template <typename T>
    Observer<T>::Observer() : m_id(&m_uidPool) { }

} // namespace se

Observable.h

#ifndef OBSERVABLE_H
#define OBSERVABLE_H

#include "Observer.h"
#include <vector>

namespace se {

    template <typename T>
    class Observable {
    public:

        void addObserver(Observer<T>* observer);
        void removeObserver(Observer<T>* observer);

    protected:

        void notify(const T& topic);

    private:
        std::vector<Observer<T>*> m_observers;
    };
} // namespace se
#endif // Include guard

Observable.cpp

#include <cstdlib>
#include <cassert>
#include "Observable.h"

namespace se {

    template <typename T>
    void Observable<T>::addObserver(Observer<T>* observer) {
        m_observers.push_back(observer);
    }

    template <typename T>
    void Observable<T>::removeObserver(Observer<T>* observer) {
        assert(observer->getId().get() < m_observers.size());

        for (size_t i = 0; i < m_observers.size(); ++i) {
            if (observer->getId() == m_observers.at(i)->getId()) {
                m_observers.erase(m_observers.begin() + i);
            }
        }
    }

    template <typename T>
    void Observable<T>::notify(const T& topic) {
        for (size_t i = 0; i < m_observers.size(); ++i) {
            m_observers.at(i)->onNotify(topic);
        }
    }
} // namespace se

The problem isn't a circular dependency one as Obervable<T> is not circularly dependent (UID.h only includes STL headers). I'm using cmake to make and gcc to compile/link. I hope you can help me out as I have spent over 7 hours trying to resolve this...

0 Answers0