c++模板类成员的声明和定义应该都放在*.h中,有普通类不一样。
如果定义放在*.cpp中,最终链接时,会报方法undefined错误。
参考:http://users.cis.fiu.edu/~weiss/Deltoid/vcstl/templates
如果非要定义在*.cpp中,一定要具体化模板类型,如下,但这样意味着你要定义无数个。
所以还是放在*.h中吧,用到的地方,编译器会帮你定义具体类型的方法。
// error
template<typename T>
A<T>::func() {
// ...
}
// OK
template<>
A<int>::func() {
// ...
}
一个例子:
// template.h
#include <iostream>
#ifndef __TEMPLATE_H_
#define __TEMPLATE_H_
class ContextAbstr {
public:
virtual void log() = 0;
};
template<typename T>
class Sam {
public:
Sam() {}
virtual ~Sam() {}
void func() {
_context.log();
return;
}
public:
static int snumber;
static void sfunc();
private:
T _context;
};
// template class's method must be define in *.h
// so when be called, different T expand to different definetion
// otherwise, ld cann't find the method
template<typename T>
void Sam<T>::sfunc() {
std::cout << "hello template static func" << std::endl;
}
// regular class's method be declared in *.h, and defined in *.cpp
// otherwise, result to mutli-definetion error
class Context : public ContextAbstr {
public:
void log();
};
#endif //__TEMPLATE_H_
// template.cpp
#include "template.h"
// template class's member also can be defined in *.cpp, but must specilize the T
template<>
int Sam<int>::snumber = 10;
template<>
int Sam<float>::snumber = 15;
// regular class's method be defined in *.cpp, avoid mutli-definetion
void Context::log() {
std::cout << "hello world from template class" << std::endl;
}
// test_template.cpp
#include "template.h"
int main()
{
Sam<Context>::sfunc();
Sam<Context>* sam = new Sam<Context>();
sam->func();
Sam<int>* sam_int = new Sam<int>();
std::cout << "int's snumber: " << sam_int->snumber << std::endl;
Sam<float>* sam_float = new Sam<float>();
std::cout << "float's snumber: " << sam_float->snumber << std::endl;
return 0;
}