0

Possible Duplicate:
Why can templates only be implemented in the header file?

Hello. I have a stupid program in c++ consisting in a header file with a class using template and a cpp file with implementations of methods.

This is the header:

namespace SynQueueing {
  template < class T, unsigned long SIZE = 0 > 
  class CommQueue { 
     public: 
        CommQueue(); 
        ~CommQueue(); 
  }
}

This is cpp

#include "myheader.h"
using namespace SynQueueing;
/* Default constructor */
template < class T, unsigned long SIZE >
CommQueue<T, SIZE>::CommQueue() {
}
/* Default destructor */
template < class T, unsigned long SIZE >
CommQueue<T, SIZE>::~CommQueue() {
}

In main I simply create an object of CommQueue

CommQueue cq;

Including CommQueue.h of course in cpp main file.

Well, compiler get crazy telling me this:

/tmp/ccvJL8VI.o: In function `main':

entry.cpp:(.text+0x2c): undefined reference to `SynQueueing::CommQueue::CommQueue()'

entry.cpp:(.text+0x10e): undefined reference to `SynQueueing::CommQueue::~CommQueue()'

entry.cpp:(.text+0x135): undefined reference to `SynQueueing::CommQueue::~CommQueue()'

collect2: ld returned 1 exit status

entry.cpp is the file where main is located. Any idea?

Thanks

Community
  • 1
  • 1
Andry
  • 3
  • 1
  • 2
  • See here : http://www.parashift.com/c++-faq-lite/templates.html#faq-35.15 – icecrime Nov 23 '10 at 12:29
  • besides the template-in-header problem, don't you also need to supply your template parameters to the instantiation? eg `CommQueue cq;` –  Nov 23 '10 at 12:34

4 Answers4

7

For templates you usually have to put the implementation in the .h/.hpp file. This may seem unnatural, but think of templates as some special "macros" that the compiler expands once you give the actual types or values (in your case, the type T, and the value SIZE). As most compilers are implemented (in your case GCC), the compiler has to find the code to insert at the time it is compiling and it sees an instantiation of the template you've defined.

Diego Sevilla
  • 28,636
  • 4
  • 59
  • 87
  • OK, thanks, works, I kept .h and .cpp separated and included both in main... is it ok? – Andry Nov 23 '10 at 12:32
  • 1
    Yes, that is feasible. People also use another extension `.ipp` to indicate template implementation, but I don't know how standard is that. – Diego Sevilla Nov 23 '10 at 12:34
  • I've seen `.tpp` be used too I think. @Andry: since your `.ipp` file should already include the `.hpp` file, you can simply include the `.ipp` for main, that'll simplify things. – Matthieu M. Nov 23 '10 at 16:22
  • I'm new to C++ (coming from a managed C#/java background), and was trying very hard to understand what was going on with my templated class implementation. Your answer helped me very much. – george.zakaryan Jan 31 '14 at 12:17
0

The template instantiation is not happening in the cpp file.

Basically, to solve this, you need to either put the entire definition in the header file, or declare the instantiation in the implementation or header file.

e.g. if you require CommQueue<int>, then put template class CommQueue<int>; in some file that is seen by the implementation file.

lijie
  • 4,811
  • 22
  • 26
0

The idea is that a template defines a "family" of functions or types. That is why you cannot simply define the functions in a .cpp file and expect to compile it once to an .obj. Every time a new template parameter T is used, a new type is created, and new functions need to be compiled.

There are infinitely many choices of T, and so the template function's definition needs to be available to the compiler every time it is instantiated, not just the compiled code in some .obj file to be linked in, like for regular functions.

Alex Budovski
  • 17,947
  • 6
  • 53
  • 58
-2

You can't define the class body inside a *.cpp file when your class is templated.
This restriction will be removed when C++0x comes out.

the_drow
  • 18,571
  • 25
  • 126
  • 193
  • Well, thank you... As I said to Diego, I included both files in my main file, it works, I just wanted to know if this is a good way to go... It seems so to me, I still can separate header from cpp... logically speaking it appears a tidy solution – Andry Nov 23 '10 at 12:33
  • You've gotten the first point wrong, your not allowed to define it within a separate translation unit to the one that it's used in. And secondly this won't be removed when C++0x comes out. – Joe D Nov 23 '10 at 12:36
  • The restriction will not be removed, only there will be introduced a way how to instantiate a template in one cpp file only using http://en.wikipedia.org/wiki/C%2B%2B0x#Extern_template – Suma Nov 23 '10 at 12:41