为什么我必须在从模板类派生的类中包含实现文件?

时间:2014-02-08 05:09:14

标签: c++

简单的问题 - 为什么我必须#include "listType.cpp"或者在这里遇到链接器错误?为什么我不能只包含标题?

stockListType.h:

#ifndef stockListType_H
#define stockListType_H

#include "listType.h"
#include "stockType.h"
#include "listType.cpp"

using namespace std;

class stockListType : public listType<stockType>
{
private:
    unique_ptr<int[]> sortIndicesByGainLoss;

public:
    void sortByStockSymbol();
    void sortByGainLoss();

    stockListType(int maxSize);
};

#endif

1 个答案:

答案 0 :(得分:2)

这是因为在传统的C ++编译器方法中,模板代码“不存在”作为“材料执行实体”,直到它被实例化为某些“真实”类型(在您的情况下为stockType)。然而,有一种称为explicit instantiation的技术允许在处理“listType.cpp”期间指定稍后您将需要一个代码实例,例如stockTypeotherTypeint。请阅读:http://msdn.microsoft.com/en-us/library/by56e477.aspx或此:http://www.cplusplus.com/forum/articles/14272/或此:How do I explicitly instantiate a template function?

使用源代码,而不是模板类和函数的预编译代码的另一个原因是,可以覆盖以后特定模板的给定模板类,方法或函数的实现参数(回想一下着名的std::cout << "Hello, World " << 1 << MyClassObject << std::endl,这是分别为每种特定类型定义operator<<(ostream&, T&)时的经典案例。

此外,如果您查看标准C ++ STL库(例如<vector><string>),您会看到类的整个代码在头文件中是正确的,或者从头文件中包含的文件文件(.tcc)甚至是一个相当复杂的文件(参见Boost.Spirit,好吧,如果你足够勇敢:))。那是因为在向量元素(stockType等)被定义之前,不可能为向量创建可执行代码。