2010-02-03 71 views
0

我正在编写一个C++自定义分配器以用于STL。当我把下面的代码在类定义,它编译:C++ STL内存分配器编译错误

#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 

但是,当我把它放在一个单独的.cpp文件,我得到以下错误。我究竟做错了什么?该错误在static_cast行。

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

回答

3

模板必须总是一个翻译单元中定义的。为了使用模板函数,模板的定义需要放在头文件中,而不是单独的.cpp文件。

+0

-1。回答一个与被问到的问题不同的问题,这个问题与编译器错误有关。未能在头文件中定义模板会导致链接错误,但甚至没有尝试进行链接。 – 2010-02-03 07:09:15

+0

不,这是一个编译器错误。编译器无法编译模板,除非在该翻译单元中定义模板。这就是头文件的作用 - 在多个实现文件中保存函数/类/变量名称。 – 2010-02-03 19:19:17

+0

你基本上说的是一个未定义的函数调用(调用一个不存在的函数)是一个链接器错误 - 事实并非如此。 – 2010-02-03 19:20:19

3

你需要把typename放在MyAlloc<T>::pointer的前面。因为MyAlloc<T>的类型取决于T,所以编译器不知道pointer是typedef还是成员变量或函数。如果你没有写typename,那么编译器会假设后者。

+1

而你不能把它放在一个单独的实现文件中。 – UncleBens 2010-02-03 07:58:03

+0

+1,但我不认为这是用户的实际问题。 – 2014-10-14 17:45:01