一直没有对 C++ 模板做过系统的学习,对于 STL 模板类或者函数,都是查查文档就直接使用。不过在翻开 STL 代码的时候,都曾注意到那些模板是放置在.h文件中的,至于为何,却是没有去想过。
今天在编写一个动态连接库的时候,才明白其中的原因。比如库里面有下面模板类
template <typename Data>
class concurrent_queue
{
public:
concurrent_queue(unsigned capacity);
~concurrent_queue();
bool push(const Data&);
void pop(Data&, int timeout = -1);
...
};
开始我习惯性的将这个模板类的实现放在 .cpp 文件里面,编译出来的 .so 都正常。但是在使用这个模板的时候,就出现问题。
比如
class Message
{
...
}
concurrent_queue<Message *> message_queue;
Message * pMsg = new Message();
message_queue.push(pMsg);
...
那么在连接上面的 .so 时,会出现下面的错误
XXX.so: undefined reference to `concurrent_queue<Message*>::push(const Message* &)'
那是因为编译器无法生成对应 Message *的实现,如果将模板类全部放置在 .h 文件里面,那么就不存在这个问题了。
模板编程对于代码重用确实有很大的实用性,不亚于继承和封装。
C++ Templates Tutorial http://www.iis.sinica.edu.tw/~kathy/vcstl/templates.htm
The declarations and definitions of the class template member functions should all be in the same header file.