views:

171

answers:

2

I'm writing a C++ custom allocator for use with STL. When I put the following code in the class definition, it compiles:

#include "MyAlloc.hpp"

#if 1
template <typename T>
typename MyAlloc<T>::pointer
MyAlloc<T>::allocate(size_type n, MyAlloc<void>::const_pointer p) {
  void *ptr = getMemory(n*sizeof(T));

  typename MyAlloc<T>::pointer tptr = static_cast<MyAlloc<T>::pointer>(ptr);
  return tptr;
}
#endif

But when I put it in a separate .cpp file, I get the following error. What am I doing wrong? The error is on the static_cast line.

g++ -c MyAlloc.cpp
MyAlloc.cpp: In member function ‘typename MyAlloc<T>::pointer MyAlloc<T>::allocate(size_t, const void*)’:
MyAlloc.cpp:9: error: expected type-specifier
MyAlloc.cpp:9: error: expected `>'
MyAlloc.cpp:9: error: expected `('
MyAlloc.cpp:9: error: expected `)' before ‘;’ token
make: *** [MyAlloc.o] Error 1

PT

+2  A: 

Templates must always be defined within a translation unit. In order to use the template function, the definition of the template needs to go in the header file, not a separate .cpp file.

Billy ONeal
This is the correct answer, hence upvote
Merlyn Morgan-Graham
Thank you for resolving the issue.
you can accept the answer then :)
yesraaj
-1. Answers a different question than the one that was asked, which had to do with a compiler error. Failure to define templates in headers leads to linking errors, but no linking was even being attempted.
Rob Kennedy
No, it's a compiler error. The compiler cannot compile the template unless the template is defined within that translation unit. That's what header files are for -- to persist function/class/variable names across multiple implementation files.
Billy ONeal
What you're essentially saying is that an undefined function call (calling a function that does not exist) is a linker error -- it is not.
Billy ONeal
+2  A: 

You need to put typename in front of MyAlloc<T>::pointer. Because the type of MyAlloc<T> depends on T, the compiler doesn't know whether pointer is a typedef or a member variable or function. If you don't write typename, then the compiler assumes the latter.

Derek Ledbetter
And you can't put it in a separate implementation file.
UncleBens