2
template <class T>
class FContainer : public QObject
{

public:

    FContainer();

    inline void append(const T &t);
    inline void clear();
    inline void remove(const T &t);

    inline const T& at(int index) const { return m_list[index]; }
    inline const T& first() const { return m_list.first(); }
    inline const T& last() const { return m_list.last(); }

    inline int indexOf(const T &t){ return m_list.indexOf(t); }
    inline int size() { return m_list.size(); }

signals:

    void appended(const T &t);
    void cleared();
    void removed(const T &t);
    void updated();


private:

    QList<T> m_list;
};

class FSystem
{
public:

    inline const FContainer<FMaterial>& materials() const { return m_materials; }
    inline const FContainer<FObject>& objects() const { return m_objects; }

    inline FContainer<FMaterial>& materials() { return m_materials; }
    inline FContainer<FObject>& objects() { return m_objects; }

    static FSystem* Instance() { return m_instance; }

private:
    FSystem();

    FContainer<FMaterial> m_materials;
    FContainer<FObject> m_objects;

    static FSystem *m_instance;
};

I am having a probem about using QObject classes as a member of a class. Compiler says:

FSystem.obj:-1: error: LNK2019: unresolved external symbol "public: __cdecl FContainer::FContainer(void)" (??0?$FContainer@VFMaterial@@@@QEAA@XZ) referenced in function "private: __cdecl FSystem::FSystem(void)" (??0FSystem@@AEAA@XZ)

FContainer Constructor Here

template <class T>
FContainer<T>::FContainer()
    : QObject()
{

}

And FSystem Constructor Here:

FSystem::FSystem() { }
  • 4
    This can't be your actual code, as it's missing semicolons. Can you create an [SSCCE](http://sscce.org/)? Anyway, I don't think this has to do with `Q_DISABLE_COPY`. Seems more like the compiler doesn't seem capable of using `QObject`'s default ctor (the one with a single parameter with defautl argument) in `A`'s default ctor. But without seeing all code involved, it's difficult to tell for sure. – Angew is no longer proud of SO Feb 21 '14 at 16:06
  • Then, I'm updating it. – Cahit Burak Küçüksütcü Feb 21 '14 at 16:11
  • 2
    My guess is you're not [implementing templates in the header file](http://stackoverflow.com/q/495021/1782465) - the `FContainer` ctor, to be exact. – Angew is no longer proud of SO Feb 21 '14 at 16:21

2 Answers2

3

Almost certainly the problem is that you define FContainer::FContainer(); in a source file rather than in the header. Since it's in a template class the compiler needs to be able to see the body at the point it's instantiated, or an explicit instantiation be made.

Mark B
  • 95,107
  • 10
  • 109
  • 188
1

It is OK to have a templated object, but since it can't have a Q_OBJECT macro, it can't have its own signals either. If you try your code, you'll see that it's impossible to connect to the object's signals.

You need to separate the signal-containing QObject from the template class. Thus your signals cannot be template-argument-dependent: you're forced to emit variants instead of T. This is precisely the approach taken in the implementation of QFutureWatcher.

class FContainerBase : public QObject {
    Q_OBJECT
public:
    FContainerBase(QObject*parent = 0);
    Q_SIGNAL void appended(const QVariant &);
    Q_SIGNAL void cleared();
    Q_SIGNAL void removed(const QVariant &);
    Q_SIGNAL void updated();
};

template <class T>
class FContainer : public FContainerBase
{
    QList<T> m_list;
public:
    FContainer() { // implementation in the header! }

    inline void append(const T &t);
    inline void clear();
    inline void remove(const T &t);

    inline const T& at(int index) const { return m_list[index]; }
    inline const T& first() const { return m_list.first(); }
    inline const T& last() const { return m_list.last(); }

    inline int indexOf(const T &t){ return m_list.indexOf(t); }
    inline int size() { return m_list.size(); }
};
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313