泛型是 C++ 模板的一個(gè)主要用途,另一個(gè)應(yīng)該是元編程了。
我個(gè)人理解,泛型的用途有兩個(gè),一為去類(lèi)型封裝,二為建立鴨子方法。
- 去類(lèi)型封裝
以 類(lèi) C 方式封裝一個(gè) int[] 數(shù)組
const int len = 10;
class ArrayInt {
private:
int datas[len];
public:
ArrayInt();
int & operator[] (int pos);
};
上述類(lèi)型只能使用 int 類(lèi)型,若使用 double 等其他類(lèi)型,或者不同長(zhǎng)度,就要手動(dòng)重復(fù)定義。于是出現(xiàn)模板實(shí)現(xiàn)。
template <typename T, int N>
class Array {
private:
T datas[N];
public:
Array();
T & operator[] (int pos);
};
但這種形式,會(huì)存在模板的一個(gè)問(wèn)題 —— 若其方法行數(shù)很多,不能內(nèi)聯(lián)時(shí),不同類(lèi)型就會(huì)產(chǎn)生不同的方法,最終導(dǎo)致編譯后的文件特別大。
這時(shí)可利用,C 常用去類(lèi)型的方法。
class Array_impl {
private:
void *datas;
public:
Array_impl(void *p) : datas(p) {}
void *get(int pos, size_t size);
};
template <typename T, int N>
class Array : protected Array_impl {
public:
Array() : Array_impl(new T[N]) {}
T & operator[] (int pos) {
assert(pos < N);
return static_case<T &>(*(Array_impl::get(pos, sizeof(T))));
}
};
- 鴨子類(lèi)型
當(dāng)你看到一只鳥(niǎo)走起來(lái)像鴨子,游泳起來(lái)鴨子,叫起來(lái)也像鴨子,那么這只鳥(niǎo)就被稱(chēng)為鴨子類(lèi)型
T sum(T a, T b) {
return a + b;
}
上面的例子,只要類(lèi)型 T 存在方法 operator+(T, T) -> T,那就能通過(guò) sum() 方法了。不管他是什么類(lèi)型,還是說(shuō),他的加法本質(zhì)實(shí)現(xiàn)的是除法,只要存在這個(gè)接口,就是好類(lèi)型。