c++模板(template)入門介紹

函數模板


代碼示例

#include<iostream>
#include<string>

using namespace std;


//這裏使用函數模板 T
template<typename T>
void swapValue(T & a, T & b) {
	T temp = a;
	a = b;
	b = temp;
}

//多個模板參數聲明方式
void func(T1 & t1,T2& t2) {
	cout << t1 << endl;
	cout << t2 << endl;
}

int main() {

	int a = 10, b = 20;
	cout << "a=" << a << "  b=" << b << endl;
	swapValue(a, b); //類型自動推導
	cout << "a=" << a << "  b=" << b << endl;

	float c = 12.34, d = 23.43;
	cout << "c=" << c << "\td=" << d << endl;
	swapValue<float>(c, d);//顯式指定類型
	cout << "c=" << c << "\td=" << d << endl;

    func(a,c);
    func<int,float>(b,d)
    
	system("pause");
	return 0;
}

函數模板的調用方式

  • 自動推導類型

    swapValue(a, b);
    
    //自動推導不會發生隱式類型轉換(例如 char-> int)
    int a =10;
    char c='v';
    swapValue(a,c) //錯誤
    
  • 顯式指定類型

    swapValue<float>(c, d);
    
    //顯式類型會發生隱式類型轉換
    int a =10;
    char c='v';
    swapValue<int>(a,c) //正確
    

注意事項

  • 自動推導出來的類型必須一致

    template<typename T>
    void swapValue(T & a, T & b) {
    	T temp = a;
    	a = b;
    	b = temp;
    }
    
    
    int a=10;
    float b=4.0;
    swapValue(a,b);//錯誤,類型不一致
    
  • 必須推斷出參數的類型才能使用

    template<typename T>
    void fun() {
    
    }
    
    int main(){
        fun(); //錯誤,雖然函數沒有使用T,但是調用的時候編譯器需要推斷出T的類型
        fun<int>();//正確,顯式指定一個類型即可
      
        return 0;
    }
    

普通函數與函數模板的調用規則

  • 如果函數模板和普通模板都可以調用,優先使用普通函數

  • 可以通過空模板參數列表強制調用模板函數

    fun<>();
    
  • 函數模板可以發生重載

  • 如果函數模板可以發生更好的匹配,則優先使用函數模板

模板具體化

#include<iostream>
#include<string>


using namespace std;

class Person {
public:
	int age;
	string name;
};

template<typename T>
void swapValue(T & a, T & b) {
	T temp = a;
	a = b;
	b = temp;
}

//當傳入Person類型時,使用下面的具體化函數模板
template<> void swapValue(Person & p1, Person& p2) {
	//int agetmp = p1.age;
	//string nametmp = p1.name;
	//p1.age = p2.age;
	//p1.name = p2.name;
	//p2.age = agetmp;
	//p2.name = nametmp;
	cout << "person swap is called..." << endl;
}



int main() {

	int a = 10, b = 20;
	cout << "a=" << a << "  b=" << b << endl;
	swapValue(a, b);
	swapValue<int>(a, b);
	cout << "a=" << a << "  b=" << b << endl;

	
	Person p1, p2;
	swapValue(p1, p2);

	system("pause");
	return 0;
}

類模板

代碼示例

class Data

#include<iostream>
#include<string>
template<class T>
class Data
{
	T data;
public:
	void setValue(T v) {
		data = v;
	}

	T getData() {
		return data;
	}
};

MainApp.cpp

int main(){
    
	Data<int> data;
	data.setValue(10);
	cout << data.getData() << endl;

	system("pause");
	return 0;
}

類模板與函數模板的區別

  • 類模板沒有自動類型推導
  • 類模板在模板參數列表有默認類型參數
template<class T=int>
class Data
{
	T data;
public:
	void setValue(T v) {
		data = v;
	}

	T getData() {
		return data;
	}
};



Data<> data; //這裏使用了默認類型參數,int,裏面可以不寫int,但是必須有尖括號<>

類模板作爲函數參數

  • 三種方式
    • 指定傳入類型
    • 函數參數模板化
    • 整個類模板化
template<class T=int>
class Data
{
	T data;
public:
	void setValue(T v) {
		data = v;
	}

	T getData() {
		return data;
	}
};


//1.指定參數類型
void func1(Data<int>& d){
    
}


//2.參數類型模板化
template<typename T>
void func2(Data<T>& d){
    // typeid()可以查看運行時參數的類型
    cout<<typeid(T).name()<<endl;
}


//3.整個類模板化
template<typename T>
void func3(T& d){
    
}

類模板分文件編寫

  • 普通類份文件編寫
    • Class.h 類的聲明
    • Class.cpp 成員函數實現
    • 在main中包含Class.h
  • 對類模板而言,這樣會產生錯誤
    • 將所有函數實現和聲明寫在一個文件中,並且命名爲 class.hpp
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章