1. 程式人生 > >模板特例化、過載

模板特例化、過載

圖  1多型提要

靜多型(Static Polymorphism)是多型性的一種,繫結發生在編譯期(compile-time)(稱為靜態繫結static-binding)。

圖  2靜多型提要

非引數化多型和引數化多型並不衝突,而且相輔相成,它們混合使用能夠帶來更大的靈活性,函式模板過載就是很好的例子。

#include<iostream>
#include<stdio.h>
using namespace std;

template<typename T>	
bool compare(const T a, const T b) {
	cout << "bool compare(const T a, const T b)" <<
		typeid(a).name() << "  " << typeid(b).name()<<endl;
	return a > b;
}

template<typename T, typename E>	//過載
bool compare(const T a, const E b) {
	cout<< "bool compare(const T a, const E b)" <<
		typeid(a).name() << "  " << typeid(b).name()<<endl;
	return a > b;
}

template<>	//特例化
bool compare<char *>(char *const a, char *const b) {
	cout <<"bool compare<char *>(char *const a, char *const b)" <<
		typeid(a).name() << "  " << typeid(b).name()<<endl;
	return strcmp(a, b) > 0;
}

int main() {
	compare(16, 17.6);		//模板過載
	compare(10, 20);		//非特例化
	compare("aaa", "bbb");	//特例化
	return 0;
}
圖  3示例程式碼執行結果

函式模板用來例項化函式,在編譯期根據模板函式使用處的引數自動生成一份該函式的程式碼,函式的入口地址就是生成函式程式碼的入口地址。

對於函式過載過載,C++中不允許只有函式型別(返回值)不同的過載:

  • 引數個數不同而引數型別相同;
  • 引數個數相同而引數型別不同;
  • 引數個數和引數型別都不相同;

值得注意的是,對於char *型別,與const結合時會產生二義性,需要記住一條規律:const修飾的是左邊或右邊第一個完整型別

bool compare(const T a, const T b)        //一般模板

bool compare<char *>(char *const

a, char *const b)    //特例化模板

是否覺得const 位置有些奇怪,最初可能會有這種貌似很正確的想法。對模板進行特例化,將所有出現T的位置都換成char *不就好了嘛?試想一下,換掉之後變成什麼了?

bool compare<char *>(const char * a, const char * b)    //錯誤示例

對於非特例化模板,const修飾的型別是T,那麼當明確T是char *時,其意義是不是指向的內容不能改變而不是指向不能改變?對,沒錯,就是這樣,這一點很值得注意。