0

It's a rather simple project which I created with sole purpose of learning how to create a Makefile. I have searched this to a reasonable extent before posting here, but could not find a solution. If I include the *.cpp files in main.cpp the program compiles fine, with no undefined references (although it still has some bugs when running, which I plan to deal with later).

main.cpp:

#include <iostream>
#include "dupqueue.h"

using std::string;
using std::cout;
using std::cin;
using std::endl;

int main()
{
    DuplicateQueue<string> dqueue;

    for(int i = 0; i < 10; i++)
    {
         string name;
         cout << "Enter a name: ";
         cin >> name;
         dqueue.enqueue(name);
         cout << endl;
    }

    dqueue.duplicate();

    cout << "Double order:\n";
    while(!dqueue.is_empty()) cout << dqueue.dequeue() << endl;

    return 0;
}

dupqueue.h:

#ifndef QUEUE_H_INCLUDED
#define QUEUE_H_INCLUDED

template <class T>
class Queue
{
public:
    Queue() : front(nullptr), rear(nullptr) {}
    ~Queue();
    Queue(const Queue& q); // explicitly disallowed
    Queue& operator=(const Queue& q); // explicitly disallowed
    void enqueue(const T& item);
    const T dequeue();
    bool is_empty() const
    {
        return front == nullptr;
    }
protected:
    struct Node
    {
        T item;
        Node * next;
        Node(const T& i) : item(i), next(nullptr) {}
    };
    Node * front;
    Node * rear;
};

template <class T>
class DuplicateQueue : public Queue<T>
{
public:
    void duplicate();
};

#endif //QUEUE_H_INCLUDED

queue.cpp:

#include "dupqueue.h"

template <class T>
Queue<T>::~Queue()
{
    Node * temp = front;
    while(!temp)
    {
        front = front->next;
        delete temp;
        temp = front;
    }
}

template <class T>
void Queue<T>::enqueue(const T& item)
{
    rear->next = new Node(item);
    rear = rear->next;
}

template <class T>
const T Queue<T>::dequeue()
{
    const T item = front->item;
    Node * temp = front;
    front = front->next;
    delete temp;
    return item;
}

dupqueue.cpp:

#include "dupqueue.h"

template <class T>
void DuplicateQueue<T>::duplicate()
{
    typename Queue<T>::Node * original_rear = Queue<T>::rear;
    typename Queue<T>::Node * temp = Queue<T>::front;
    while(temp != original_rear->next)
    {
        Queue<T>::rear->next = new typename Queue<T>::Node(temp->item);
        Queue<T>::rear = Queue<T>::rear->next;
        temp = temp->next;
    }
}

Makefile:

main: main.o queue.o dupqueue.o
    g++ -o main main.o queue.o dupqueue.o

main.o: main.cpp dupqueue.h queue.cpp dupqueue.cpp
    g++ -c main.cpp

queue.o: queue.cpp dupqueue.h
    g++ -c queue.cpp

dupqueue.o: dupqueue.cpp dupqueue.h
    g++ -c dupqueue.cpp

clean:
    rm -f main *.o

make output:

g++ -o main main.o queue.o dupqueue.o
main.o: In function `main':
main.cpp:(.text+0x83): undefined reference to `Queue<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::enqueue(
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
main.cpp:(.text+0xb7): undefined reference to `DuplicateQueue<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >:
:duplicate()'
main.cpp:(.text+0xf0): undefined reference to `Queue<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::dequeue(
)'
main.o: In function `DuplicateQueue<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~DuplicateQueue()':
main.cpp:(.text._ZN14DuplicateQueueINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEED2Ev[_ZN14DuplicateQueueINSt7__cxx1112basic_stringIcSt1
1char_traitsIcESaIcEEEED5Ev]+0x25): undefined reference to `Queue<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> 
> >::~Queue()'
collect2: error: ld returned 1 exit status
make: *** [Makefile:2: main] Error 1
WeakestTopology
  • 153
  • 2
  • 10
  • Have you tried putting all the code from the templated class into the .h file? – JGroven Feb 28 '17 at 18:57
  • @user3112926 No, but why would that be necessary? I believe I should be able to compile with the methods in other files. – WeakestTopology Feb 28 '17 at 19:05
  • See the answer posted above. (http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – JGroven Feb 28 '17 at 19:10

0 Answers0