天天看點

C++函數模闆

函數模闆提供了一種函數行為,該函數行為可以用多種不同的類型進行調用,也就是說,函數模闆代表一個函數家族,這些函數的元素是未定的,在使用的時候被參數化。

下面舉一個簡單的例子:

這個模闆定義指定了一個“傳回兩個值中最大者”的函數家族,這兩個值通過函數參數a , b傳遞給函數模闆的,而參數的類型還沒有确定,用模闆參數t來代替。

其中,typename可以用class來代替,但是建議使用typename

完整代碼如下:

模闆參數可以根據我們傳遞的實參來決定,如果我們傳遞了兩個int給參數類型t const&,那麼c++編譯器得出結論:每個t都必須正确的比對,如果此時傳遞的實參為:max(4, 4.2),則出現編譯錯誤

有3種方法來處理上面的錯誤:

1、對實參進行強制類型轉換,使它們可以互相比對:

max(static_cast<double>(4), 4.2);

2、顯示指定(或限定)t的類型:

max<double>(4, 4.2)

3、指定兩個參數可以具有不同的類型

函數模闆有2種類型的參數:

1、模闆參數:位于函數模闆名稱的前面,在一對尖括号内部進行聲明:

template<typename t>

2、用參數:位于函數模闆名稱之後,在一對圓括号内部進行聲明:

...max(t const& a, t const& b)

可以聲明任意數量的模闆參數,在函數模闆的内部,不能指定預設的參數。

可以引入第三個模闆實參類型,來定義函數模闆的傳回類型:

行得通,但是很麻煩

還有一種方法是隻顯示的指定第一個實參,而讓演繹過程推導出其餘的實參。

和普通函數一樣,函數模闆也可以被重載,示例代碼如下:

  下面的更有用的例子将會為指針和普通的c字元串重載這個求最大值的模闆:

以上在所有實作重載裡面,都是通過引用來傳遞每個執行個體的,但是一般而言,在重載函數模闆的時候,最好隻是改變那些需要改變的内容,應該把改變限制在以下兩個方面:

改變參數的數目或顯式地指定模闆參數

 對于以上的重載,如果改為基于c-string的max()函數,通過傳值來傳遞參數,就不能實作3個參數的max()版本:

錯誤在于:如果對3個c-string調用max,則語句return max(max(a, b), c);将産生錯誤

原因是對于c-string而言,max(a, b)産生了一個新的臨時局部值,該值有可能被外面的max函數以傳引用的方式傳回,将導緻傳回無效的引用。

繼續閱讀