sayhey69
sayhey69

Reputation: 1099

undefined reference when using templates

Keep on getting undefined reference which other answers say should be linking issue. Am I not compiling this correctly? Or is there something wrong in the code? I've tried throwing main into stack.cpp and it compiles and runs fine, but I'm not sure what else needs to be done to link main.o and stack.o and why it suddenly is throwing a fit now that I've added this one file.

stack.h:

#ifndef STACK_INCLUDED
#define STACK_INCLUDED

#include <cstddef>

template<typename T> struct Node {
  Node(T _data, Node<T> * _next) : data(_data), next(_next) {}
  T data;
  Node<T> *next;
};

template<class T>
class Stack {
 private:
  Node<T> *first;
 public:
  Stack(void);
  bool isEmpty(void);
  void push(T n);
  T pop(void);
};

#endif

stack.cpp:

#include "stack.h"

template<class T>
Stack<T>::Stack(void) {
  first = NULL;
}

template<class T>
bool Stack<T>::isEmpty(void) {
  return first == NULL;
}

template<class T>
void Stack<T>::push(T n) {
  Node<T> *oldfirst = first;
  Node<T> *newfirst = new Node<T>(n, oldfirst);
  first = newfirst;
  first->next = oldfirst;
}

template<class T>
T Stack<T>::pop(void) {
  T data = first->data;
  first = first->next;
  return data;
}

main.cpp:

#include <iostream>

#include "stack.h"

using namespace std;

int main(void) {
  Stack<int> s;

  if (!s.isEmpty()) {
    cout << "not empty" << endl;
  }

  return 0;
}

Try to compile:

$ g++ stack.cpp -c
$ g++ main.cpp -c
$ g++ main.o stack.o
main.o: In function `main':
main.cpp:(.text+0x10): undefined reference to `Stack<int>::Stack()'
main.cpp:(.text+0x1c): undefined reference to `Stack<int>::isEmpty()'
collect2: ld returned 1 exit status

Upvotes: 0

Views: 486

Answers (3)

baju
baju

Reputation: 511

You can seperate implementation from header but you should use 'extern templates' from C++11.

Upvotes: 1

mornfall
mornfall

Reputation: 428

You can't use separate compilation with templates like this. The compiler needs to see the template definitions (the template function bodies) at the point of use, or it doesn't know how to generate code for the int instance of Stack<T>::Stack() (etc.). You could explicitly ask for the instances in your stack.cpp, but you are better off moving the function definitions into the header file.

Upvotes: 3

nobody
nobody

Reputation: 20174

You need to have the entire template class definition in the header.

Upvotes: 4

Related Questions