Search code examples
c++classtemplates

Templates and separate compilation


I want to write a program in C++ with separate compilation and I wrote this:

main.cpp

#include <iostream>
#include "Stack.h"
using namespace std;
int main(int argc,char* argv[])
{
    Stack<int> st;
    st.push(1);
    return 0;
}

Stack.h

#ifndef _STACK_H
#define _STACK_H
template<typename T> 
class Stack
{
private:
struct Node
{
    Node* _prev;
    T _data;
    Node* _next;
};
int _size;
Node* _pos;

public:
    Stack();
    T pop();
    void push(T  const &el);
    int getSize() const;
};
#endif

Stack.hpp

#include "Stack.h"
#include <malloc.h>
template <typename T>
Stack<T>::Stack()
{
    _size = 0;
    _pos = (Node*)malloc(sizeof(Node));
    _pos->_prev = NULL;
    _pos->_next = NULL;
}
template <typename T>
T Stack<T>::pop()
{
    if (_size == 0)
        return NULL;
    T tmp = _pos->_data;
    if (_pos->_prev == NULL)
        free(_pos);
    else
    {
        _pos->_prev->_next = _pos->_next;
        if (_pos->_next != NULL)
        {
    _pos->_next->_prev = _pos->_prev;
        }
        free(_pos);
    }
    _size--;
    return tmp;
}
template <typename T>
void Stack<T>::push(T const &el)
{
    Node* n = (Node*)malloc(sizeof(Node));
    _pos->_next = n;
    n->_prev = _pos;
    n->_data = *el;
    _pos = n;
    _size ++;
}
template<typename T> 
int Stack<T>::getSize() const {return _size;};

I compiled the program with g++ and I get this error:

ccyDhLTv.o:main.cpp:(.text+0x16): undefin
ed reference to `Stack<int>::Stack()'
ccyDhLTv.o:main.cpp:(.text+0x32): undefin
ed reference to `Stack<int>::push(int const&)'
collect2: ld returned 1 exit status

I know that the problem is because I'm using templates but I do not know how to fix it.

OS - Windows compilation line - g++ main.cpp Stack.h Stack.hpp -o main.exe


Solution

  • Template classes need to have the method definitions inside the header file.

    Move the code you have in the .cpp file inside the header, or create a file called .impl or .imp, move the code there, and include it in the header.

    The compiler needs to know the method definitions to generate code for all specializations.

    Before you ask, no, there is no way to keep the implementation outside the header.