模板的聲明、定義分爲兩種。
1 將模板的聲明和定義都放在頭文件中,在主程序的文件中包含此頭文件即可
2 將模板的聲明和定義分開編寫。
在《C++ primer》教材中,將模板的聲明和定義分別放在頭文件(.h)和(.cpp)中的模板編譯模型分爲兩種,一種是包含編譯模型(inclusion compilation model),另一種是分別編譯模型(separate compilation model)。其中,包含編譯模型,所有編譯器都支持,但是分別編譯模型,大部分編譯器(包括VS2017)卻不支持。
2.1 包含編譯模型
以下列例子爲例:
//頭文件 head.h
#pragma once
#ifndef TEMPLATE_DEMO_01
#define TEMPLATE_DEMO_01
template<typename TT> void gg(const TT &t);
template<typename TT> void ggg(const TT &t);
#include"head.cpp" //注意這裏要添加函數模板定義的源文件的名字,head.cpp
#endif // !1
對應的模板函數的定義在對應的源文件中:
//函數模板的定義 head.cpp
#include "stdafx.h"
#include<iostream>
using namespace std;
template<typename TT> void gg(const TT &t)
{
cout << 222 << endl;
}
template<typename TT> void ggg(const TT &t)
{
cout << 333 << endl;
}
主程序如下:
//主程序如下
#include "stdafx.h"
#include<iostream>
#include"head.h" //這裏是函數模板的頭文件名稱
#include<string>
using namespace std;
int main()
{
string z("I am Chinese");
gg(z); //調用函數模板
ggg(z); //調用函數模板
system("pause");
return 0;
}
在VS中,函數模板可以用包含編譯的方法去寫代碼,但是類模板卻不可以這麼做(反正我是沒做出來),我把類模板的定義放在了頭文件中,把函數模板的定義放在對應的源文件中,這樣做也是可以的,在此只舉出頭文件的代碼例子:
//頭文件head.h,包含類模板的聲明和定義,函數模板的聲明。
//函數模板的定義放在了對應的源文件裏,和上面的head.cpp內容一樣
#ifndef TEMPLATE_DEMO_01
#define TEMPLATE_DEMO_01
template<typename TT> void gg(const TT &t);
template<typename TT> void ggg(const TT &t);
template<class Type>
class A
{
private:
int x;
public:
A() :x(0) {};
template<typename TT> void g(const TT &t);
int f();
};
template<class Type>
int A<Type>::f()
{
cout << x << endl;
return 55;
}
template<class Type> template<typename TT>
void A<Type>::g(const TT &t)
{
cout << t << endl;
}
#include"head.cpp" //記得加源文件
#endif //
2.2 在網上我發現了一個不錯的代碼,可以將模板的聲明與定義完全分開,在主程序中包含源程序即可:
//head.h 模板聲明
#pragma once
#ifndef TEMPLATE_DEMO_01
#define TEMPLATE_DEMO_01
template<typename T> void fun(const T &t);
template<class Type>
class A
{
private:
int x;
public:
A() :x(0) {};
template<typename TT> void g(const TT &t);
int f();
};
//#include"head.cpp" //這裏不再需要包含源程序
#endif // !1
頭文件對應的源程序裏面,包含對函數模板和類模板的具體定義:
//head.cpp 模板的定義
#include "stdafx.h"
#include<iostream>
#include"head.h" //這裏包含模板聲明的頭文件
using namespace std;
template<typename T> void fun(T &t)
{
cout << t << endl;
}
template<class Type>
int A<Type>::f()
{
cout << x << endl;
return 55;
}
template<class Type> template<typename TT>
void A<Type>::g(const TT &t)
{
cout << t << endl;
}
主程序中代碼如下:
// main.cpp: 定義控制檯應用程序的入口點。
#include "stdafx.h"
#include<iostream>
#include"head.cpp" //注意:這裏包含的是模板的定義的源文件,不是模板聲明的頭文件
#include<string>
using namespace std;
int main()
{
int x = -666;
short y =1;
string z("I am Chinese");
fun(x); //調用函數模板
fun(y); //調用函數模板
fun(z); //調用函數模板
A<int> a; //類模板實例化
a.f(); //對象a調用函數
a.g(z); //對象a調用函數模板
system("pause");
return 0;
}
2.3 分別編譯模型,這裏用關鍵字export進行聲明,但是VS不支持關鍵字的這種使用方法,所以小心啊小心。