如何编译位于C ++中不同文件的模板?

时间:2011-02-01 23:56:41

标签: c++ visual-c++ templates

当我将所有源代码放在一个文件中时,程序会成功构建。但是,当我将它们分成头文件时,我收到链接错误。

我的计划的主要内容: // C ++ _ Class_Templates.cpp

#include <iostream>
#include <vector>
#include "Queue.h"

using namespace std;

//Usage for C++ class templates
void main()
{
     MyQueue<int> q;
     q.Add(1);
     q.Add(2);
}

Queue.h看起来像这样

#pragma once
#include <vector>

template <typename T>
class MyQueue
{
     std::vector<T> data; 
   public:
     void Add(T const &);
     void Remove();
     void Print();

};

并且Queue.cpp看起来像这样:

#include "Queue.h"

template <typename T> void MyQueue<T> ::Add(T const &d)
{
     data.push_back(d);
}

当我尝试构建它时,我收到此错误:

 1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall
 MyQueue<int>::Add(int const &)" (?Add@?$MyQueue@H@@QAEXABH@Z) referenced in function _main

2 个答案:

答案 0 :(得分:11)

简短的回答是:“你没有。”

更长的答案是:嗯,它与简短答案基本相同。有关更多信息,请参阅C ++ FAQ Lite条目"Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?"除了某些有限使用场景(例如,当您使用一小组已知参数时,您将使用该模板,并且可以使用这些类型显式实例化它) ,当您尝试使用模板时,模板的定义必须可用。

答案 1 :(得分:1)

分离模板的声明和定义并非易事。

编译器必须看到定义能够编译特化,但它也必须知道要使用的参数。 C ++被设计为一次编译一个“编译单元”,这两个部分(定义和参数)必须同时可见。

因此,要么将所有特殊化的列表放在模板的实现文件中,要么将整个定义放在.h文件中。然而,这两种解决方案都存在缺陷。

请参阅this answer您遇到的同一问题,以获得更完整的解释。