當我們執行一段代碼時,如果有一個循環調用一個函數,那就有不斷的函數棧貞的開闢與回退,就造成效率底下,在c++中我們可以用模板解決這個問題,模板在編譯階段就被確定。
template<typename T>//二元比較器
class Less
{
public:
typedef T value_type;
bool call(T a1,T a2)
{
return a1<a2;
}
private:
};
template<typename T>//一元比較器
class Greater
{
public:
typedef T value_type;
Greater(T value) :_value(value){}
bool call(T a1)
{
return a1 > _value;
}
private:
T _value;
};
而我們當用一個函數調用時:
template<typename T,typename compare>
int find(T*array, int len, compare comp)
{
for (int i = 0; i < len; i++)
{
if (comp.call(array[i]))
{
return i;
}
}
return -1;
}
如何在不改變find函數模板的情況下,讓find既能調用一元比較器又能調用二元比較器呢?
我們定義一個綁定器,將二元比較器的一個值綁定,就變成了一元比較器,find就成了通用的模板了,比較器定義如下:
template<typename compare>
class _bind
{
public:
typedef typename compare::value_type T;//獲取數組中的元素的類型
_bind(compare comp,T a)
{
_value = a;
_comp = comp;
}
bool call(T a)
{
return _comp.call(a, _value);
}
private:
T _value;
compare _comp;
};
綁定器就相當於重新定義了一個模板,將一個參數變爲自己的成員屬性,然後再自己模板內部吧這個參數傳遞給二元比較器,也相當於給二元比較器重新加了一個外包裝。但是此模板在調用時必須把參數寫全,類模板無法自己推演參數參數類型調用時如下:
//int index = find(arr, 5, _bind<int, Less<int>>(Less<int>(),3 ));//_bind類模板不存在參數的推演,所以必須寫明參數
於是我們就加給此綁定器加了一個外包裝,讓他變成一個函數模板,函數模板就可以自己根據傳遞的參數自己推演參數列表,函數如下:
template<typename compare>//用一個函數將類包裝
_bind<compare> _mybind(compare comp, typename compare::value_type a)//typename 指明後面是類型名
{
return _bind<compare>(comp, a);
}
此時調用:
int index = find(arr, 5, _mybind(Less<int>(), 3));//將類模板轉換成相應的函數模板,因爲函數模板存在參數推演,就簡化