0

I have created my own blocking queue and I'm having some trouble figuring out why I get a linker error (note this is a Qt app in Visual Studio 2010):

#ifndef BLOCKING_QUEUE_H
#define BLOCKING_QUEUE_H

#include <QObject>
#include <QSharedPointer>
#include <QWaitCondition>
#include <QMutex>
#include <queue>

namespace TestingNS
{
    template<typename Data>
    class BlockingQueue
    {
    private:
        std::queue<QSharedPointer<Data>> _queue;
        QMutex _mutex;
        QWaitCondition _monitor;
        volatile bool _closed;

    public:
        BlockingQueue();

        void Close();

        size_t Size();

        void Empty();

        bool IsClosed();

        bool Enqueue(QSharedPointer<Data> data);

        bool TryDequeue(QSharedPointer<Data>& value, unsigned long time = ULONG_MAX);
    };
}
#endif //BLOCKING_QUEUE_H

The implementation is a bit longer, so I have a pastie for it: http://pastie.org/5368660

The program entry point looks like this:

#include <QtCore/QCoreApplication>
#include <QTimer>
#include <iostream>
#include "BlockingQueue.h"

using namespace std;
using namespace TestingNS;

class Item
{

};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    BlockingQueue<Item> queue;

    cout << "Press any key to exit!" << endl;

    char in;
    cin.get(in);
    QTimer::singleShot(0, &a, SLOT(quit()));

    return a.exec();
}

The linker error I get is:

Error   1   error LNK2019: unresolved external symbol "public: __thiscall TestingNS::BlockingQueue<class Item>::BlockingQueue<class Item>(void)" (??0?$BlockingQueue@VItem@@@TestingNS@@QAE@XZ) referenced in function _main

I don't understand why the linker can't find the constructor (nor any other method from BlockingQueue). Any ideas?

Kiril
  • 39,672
  • 31
  • 167
  • 226
  • Where is the implementation of BlockingQueue? – imreal Nov 12 '12 at 23:05
  • 2
    Looks like another dupe for [Why can templates only be implemented in the header file?](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file). – Jesse Good Nov 12 '12 at 23:06
  • @Nick see the pastie link in my question. – Kiril Nov 12 '12 at 23:11
  • @JesseGood ah, I just realized that [I shot myself in the foot in C++](http://www.fullduplex.org/humor/2006/10/how-to-shoot-yourself-in-the-foot-in-any-programming-language/) and it's not the first time I do it. – Kiril Nov 12 '12 at 23:18
  • Even if "the implementation is a bit longer", you should consider including it in the actual question. Otherwise, when the pastie link expires, that information becomes unavailable for future reference. – Fred Nov 13 '12 at 01:58
  • @Fred the implementation is irrelevant in this case. – Kiril Nov 13 '12 at 04:34

1 Answers1

3

It's template, you have to put the implementation inside BlockingQueue.h

For a while, the standard did provide the keyword export to allow such a separate implementation file. But not many vendors implemented it. C++11 discontinues that use of export but reserves the export keyword for possible future use.)

Templates have to be used in conjunction with requests for particular instantiations of templates.

billz
  • 44,644
  • 9
  • 83
  • 100