Search code examples
c++c++11linker

C++ linker error - cannot see why its not linking? (full complete code example included)


This is my code and I am getting a linking problem on the constructor:

#ifndef LOCKFREEQUEUE_H
#define LOCKFREEQUEUE_H

#include <atomic>
#include <memory>

template<typename T>
class lock_free_queue
{
    private:
        struct node
        {
            std::shared_ptr<T> data;
            node* next;
            node():next(nullptr){}
        };

        std::atomic<node*> head;
        std::atomic<node*> tail;

        node* pop_head()
        {
            node* const old_head=head.load();
            if(old_head==tail.load())
            {
                return nullptr;
            }
            head.store(old_head->next);
            return old_head;
        }

        lock_free_queue(const lock_free_queue& other);
        lock_free_queue& operator=(const lock_free_queue& other);

    public:
        lock_free_queue();
        ~lock_free_queue();
        std::shared_ptr<T> pop();
        void push(T new_value);
};

Source file:

#include "lock_free_queue.h"

template<typename T>
lock_free_queue<T>::lock_free_queue(const lock_free_queue& other)
{
}

template<typename T>
lock_free_queue<T>& lock_free_queue<T>::operator=(const lock_free_queue& other)
{
}

template<typename T>
lock_free_queue<T>::lock_free_queue():head(new node),tail(head.load())
{
}

template<typename T>
lock_free_queue<T>::~lock_free_queue()
{
    while(node* const old_head=head.load())
    {
        head.store(old_head->next);
        delete old_head;
    }
}

template<typename T>
std::shared_ptr<T> lock_free_queue<T>::pop()
{
    node* old_head=pop_head();
    if(!old_head)
    {
        return std::shared_ptr<T>();
    }
    std::shared_ptr<T> const res(old_head->data);
    delete old_head;
    return res;
}

template<typename T>
void lock_free_queue<T>::push(T new_value)
{
    std::shared_ptr<T> new_data(std::make_shared<T>(new_value));
    node* p=new node;
    node* const old_tail=tail.load();
    old_tail->data.swap(new_data);
    old_tail->next=p;
    tail.store(p);
}

Main:

#include "lock_free_queue.h"

int main(){
    lock_free_queue<int>* my_queue = new lock_free_queue<int>();
    my_queue->push(3);
    return 1;
}

Linker error:

Main.obj : error LNK2019: unresolved external symbol "public: __cdecl lock_free_queue<int>::lock_free_queue<int>(void)" (??0?$lock_free_queue@H@@QEAA@XZ) referenced in function main
Main.obj : error LNK2019: unresolved external symbol "public: void __cdecl lock_free_queue<int>::push(int)" (?push@?$lock_free_queue@H@@QEAAXH@Z) referenced in function main

I can't see why these aren't linking?


Solution

  • The template class definition and its member function realizations shall be in one header file.