VS2017 函數模板和類模板的聲明、定義和使用

   

模板的聲明、定義分爲兩種。

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不支持關鍵字的這種使用方法,所以小心啊小心。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章