0

I have a queue class that has this definition:

    template <typename T>
    class SharedQueue
    {
    public:
        SharedQueue();
        ~SharedQueue();
    };

In test.h, I have as one of the variables in the class:

SharedQueue<int>* sharedQueue;

In test.cpp, I am trying to do:

sharedQueue = new SharedQueue<int>;

But, for some reason, it's giving me errors. Am I not initializing the template class properly?

I looked and noticed this: Why can templates only be implemented in the header file? but it's difficult to see how relevant that is to me

UPDATE: The error is

Error   LNK2001 unresolved external symbol "public: __cdecl SharedQueue<int>::SharedQueue<int>(void)" (??0?$SharedQueue@H@@QEAA@XZ) Demo    C:\test\foo.obj 1       

1 unresolved externals

UPDATE TWO:

SharedQueue.h:

#pragma once

#include <queue>
#include <mutex>
#include <condition_variable>

template <typename T>
class SharedQueue
{
public:
    SharedQueue();
    ~SharedQueue();
    T& front();
    void pop_front();
    void push_back(const T& item);
    void push_back(T&& item);
    int size();
    bool empty();

private:
    std::deque<T> queue_;
    std::mutex mutex_;
    std::condition_variable cond_;
};

SharedQueue.cpp:

#include "SharedQueue.h"

template <typename T>
SharedQueue<T>::SharedQueue()
{

}

template <typename T>
SharedQueue<T>::~SharedQueue()
{

}

template <typename T>
T& SharedQueue<T>::front()
{
    std::unique_lock <std::mutex> mlock(mutex_);
    while (queue_.empty())
    {
        cond_.wait(mlock);
    }
    return queue_.front();
}

template <typename T>
void SharedQueue<T>::pop_front()
{
    std::unique_lock<std::mutex> mlock(mutex_);
    while (queue_.empty())
    {
        cond_.wait(mlock);
    }
    queue_.pop_front();
}

template <typename T>
void SharedQueue<T>::push_back(const T& item)
{
    std::unique_lock<std::mutex> mlock(mutex_);
    queue_.push_back(item);
    mlock.unlock();
    cond_.notify_one();
}

template <typename T>
void SharedQueue<T>::push_back(T&& item)
{
    std::unique_lock<std::mutex> mlock(mutex_);
    queue_.push_back(std::move(item));
    mlock.unlock();
    cond_.notify_one();
}

template <typename T>
int SharedQueue<T>::size()
{
    std::unique_lock<std::mutex> mlock(mutex_);
    int size = queue_.size();
    mlock.unlock();
    return size;
}
cmed123
  • 675
  • 6
  • 18
  • When asking about errors, always include them in full and complete in the question. And if the errors are text then copy-paste them as text. – Some programmer dude Jan 10 '20 at 07:58
  • 1
    Considering the error shown (after your edit) then [Why can templates only be implemented in the header file?](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) indeed seems to be relevant. Where do you define (implement) the `SharedQueue` constructor? My guess is that it's in a separate source file, and not the header file. – Some programmer dude Jan 10 '20 at 08:00
  • @songyuanyao If I write extern, it tells me "invalid storage class for a class member" though – cmed123 Jan 10 '20 at 08:00
  • @Someprogrammerdude Hm interesting. I implement the constructor in SharedQueue.cpp. I include SharedQueue.h in test.h and I include test.h in test.cpp – cmed123 Jan 10 '20 at 08:01
  • 1
    "I implement the constructor in `SharedQueue.cpp`" - it should be implemented in `SharedQueue.h`. – Evg Jan 10 '20 at 08:04
  • @Evg Hm I just updated my post with my implementation of it. That's what I've followed for my other classes which work fine though. Is there something special with template classes? – cmed123 Jan 10 '20 at 08:07
  • 1
    Yes. They can't be implemented in `.cpp` as explained in the question you mentioned in your post. – Evg Jan 10 '20 at 08:08
  • @Evg Interesting. I also just tried including SharedQueue.cpp in test.h and it built without errors. It seems that this is also an option? Or am I mistaken? – cmed123 Jan 10 '20 at 08:14
  • 1
    This works because now compiler can see definitions, not just declarations. But we usually [don't include](https://stackoverflow.com/questions/1686204/why-should-i-not-include-cpp-files-and-instead-use-a-header) `.cpp` files. If you want to put implementation into a separate file, and then include it, do it, but don't use `.cpp` extension for that file. Use `.h` or something like `.i` or `.inc`. `#include` just performs text substitution, there is [no magic](https://stackoverflow.com/questions/35720656/how-does-include-work-in-c) in it. – Evg Jan 10 '20 at 08:27
  • 1
    @Evg Got it, that makes sense. Thank you very much – cmed123 Jan 10 '20 at 08:38

0 Answers0