views:

109

answers:

2

Okay, I'm trying to implement a templated class of an array-based queue called Queue. Here's how I did it. First, is this the right way to implement a templated class? The problem is, when I try to compile, I get the error messages

undefined reference to 'Queue::Queue()'
undefined reference to 'Queue::~Queue()'

Any ideas what's wrong? Am I declaring it wrong or implementing it wrong?

queue.h

#ifndef __QUEUE_H__
#define __QUEUE_H__

template <class T>
class Queue
{
    int first;
    T* array;

  public:
    Queue();
    ~Queue;
    void enqueue(T next);
    T dequeue();
    bool is_empty();
    bool is_full();

};

#endif

queue.cpp

#include "queue.h"

template <class T> Queue<T>::Queue(){
    ...
}
template <class T> Queue<T>::~Queue(){
    ...
}
template <class T> void Queue<T>::enqueue(T next){
    ...
}
template <class T> T Queue<T>::dequeue(){
    ...
}
template <class T> bool Queue<T>::is_empty(){
    ...
}
template <class T> bool Queue<T>::is_full(){
    ...
}

main.cpp

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

using namespace std;

int main(){
  Queue<int> test;
  return 0;
}
+9  A: 

Several issues:

  • The cause of your problem - C++ does not really support splitting templates into .h and .cpp files - you need to put everything in the header

  • The name __QUEUE_H__ is reserved for the C++ implementation, as are all names that contain double-underscores or begin with an underscore and an uppercase letter. You are not allowed to create such names in your own code.

  • You probably will find it more convenient to implement the queue in terms of a std::deque, rather than a C-style array

  • I assume you are doing this as a learning exercise, but if not you should know that the C++ Standard Library already contains a std::queue template class.

anon
@Neil, The reservation of names that begin with a double-underscore is only for global scope, isn't it?
luke
+1: for the `__` -- funny this seems to be the most widely broken rule of the C++ standard.
Kornel Kisielewicz
@luke No - that is for names that begin with an underscore and a *lowercase* letter. The names I describe are reserved in all circumstances.
anon
@luke: cf. http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier/228797#228797
James McNellis
Ah, I wasn't aware of the distinction. Thanks Neill/James.
luke
+1  A: 

A template is really just a fancy form of macro that the compiler is aware of, for nearly every implementation of C++. The definitions have to be present so that the compiler can generate code in place of the template.

Joel