There is a problem with this code and I can't understand it. It seems the problem happens within the linking phase as I've googled, but in my case I think there is something wrong with my code, not in toolchains, but I just couldn't solve it after hours and hours of trying. I'd be happy if you help me correcting it. I'm using Code::Blocks, and the latest version of MinGW.
main.cpp
#include <iostream>
#include <string>
#include "threadsafequeue.hpp"
using namespace std;
int main(){
    threadsafe_queue<string> Q;
    threadsafe_queue<string> X;
    X.empty();
    try{
        string s;
    }catch(empty_queue ex){
        cout << ex.what() << endl;
    }
    return 0;
}
threadsafe_queue.cpp
#include "threadsafe_queue.hpp"
template <typename T>
threadsafe_queue<T>::threadsafe_queue(const threadsafe_queue& other){
    std::lock_guard<std::mutex> lock(other.m);
    threadsafe_queue<T>::data = other.data;
}
template <typename T>
void threadsafe_queue<T>::push(T new_value){
    std::lock_guard<std::mutex> lock(threadsafe_queue<T>::m);
    threadsafe_queue::data.push(new_value);
}
template <typename T>
std::shared_ptr<T> threadsafe_queue<T>::pop(){
    std::lock_guard<std::mutex> lock(threadsafe_queue<T>::m);
    if(data.empty()) throw empty_queue();
    std::shared_ptr<T> const res(std::make_shared<T>(threadsafe_queue<T>::data.front()));
    threadsafe_queue<T>::data.pop();
    return res;
}
template <typename T>
void threadsafe_queue<T>::pop(T& value){
    std::lock_guard<std::mutex> lock(threadsafe_queue::m);
    if(data.empty()) throw empty_queue();
    value = threadsafe_queue::data.front();
    threadsafe_queue::data.pop();
}
template <typename T>
bool threadsafe_queue<T>::empty(){
    std::lock_guard<std::mutex> lock(threadsafe_queue<T>::m);
    return threadsafe_queue<T>::data.empty();
}
threadsafe_queue.hpp
#include <exception>
#include <memory>
#include <mutex>
#include <queue>
#ifndef THREADSAFE_QUEUE_HPP_INCLUDED
#define THREADSAFE_QUEUE_HPP_INCLUDED
struct empty_queue : std::exception
{
    virtual const char * what() const throw()
    {
        return "The Queue is Empty.";
    };
};
template <typename T>
class threadsafe_queue
{
private:
    std::queue<T> data;
    mutable std::mutex m;
public:
    threadsafe_queue() {};
    threadsafe_queue(const threadsafe_queue& other);
    threadsafe_queue& operator= (const threadsafe_queue&) = delete;
    void push(T new_value);
    std::shared_ptr<T> pop();
    void pop(T& value);
    bool empty();
};
#endif // THREADSAFE_QUEUE_HPP_INCLUDED
And the error is :
...\ThreadSafeQueue\main.cpp|9|undefined reference to `threadsafe_queue::empty()'|
 
     
     
    