類模板、綁定器與參數推演

當我們執行一段代碼時,如果有一個循環調用一個函數,那就有不斷的函數棧貞的開闢與回退,就造成效率底下,在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));//將類模板轉換成相應的函數模板,因爲函數模板存在參數推演,就簡化
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章