天天看點

《C++ Templates中文版》——2.3 模闆參數

本節書摘來自異步社群出版社《c++ templates中文版》一書中的第2章,第2.3節,作者: 【美】david vandevoorde , 【德】nicolai m. josuttis,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

函數模闆有兩種類型的參數。

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

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

你可以根據需要聲明任意數量的模闆參數。然而,在函數模闆内部(這一點和類模闆有差別),不能指定預設的模闆實參[4]。例如,你可以定義一個“兩個調用參數的類型可以不同的”max()模闆:

這看起來是一種能夠給max()模闆傳遞兩個不同類型調用參數的好方法,但在這個例子中,這種方法是有缺點的。主要問題是:必須聲明傳回類型。對于傳回類型,如果你使用的是其中的一個參數類型,那麼另一個參數的實參就可能要轉型為傳回類型,而不會在意調用者的意圖。c++并沒有提供一種“指定并且選擇一個‘最強大類型’”的途徑(然而,你可以使用一些tricky模闆程式設計來提供這個特性,詳見15.2.4小節)。于是,取決于調用實參的順序,42和66.66的最大值可以是浮點數66.66,也可以是整數66。另一個缺點是:把第2個參數轉型為傳回類型的過程将會建立一個新的局部臨時對象,這導緻了你不能通過引用[]來傳回結果。是以,在我們的例子裡,傳回類型必須是t1,而不能是t1 const&。

因為調用參數的類型構造自模闆參數,是以模闆參數和調用參數通常是相關的。我們把這個概念稱為:函數模闆的實參演繹。它讓你可以像調用普通函數那樣調用函數模闆。

然而,如前所述,針對某些特定的類型,你還可以顯式地執行個體化該模闆:

當模闆參數和調用參數沒有發生關聯,或者不能由調用參數來決定模闆參數的時候,你在調用時就必須顯式指定模闆實參。例如,你可以引入第3個模闆實參類型,來定義函數模闆的傳回類型:

然而,模闆實參演繹并不适合傳回類型[6],因為rt不會出現在函數調用參數的類型裡面。是以,函數調用并不能演繹出rt。于是,你必須顯式地指定模闆實參清單。例如:

到目前為止,我們隻是考察了顯式指定所有函數模闆實參的例子,和不顯式指定函數任何模闆實參的例子。另一種情況是隻顯式指定第一個實參,而讓演繹過程推導出其餘的實參。通常而言,你必須指定“最後一個不能被隐式演繹的模闆實參之前的”所有實參類型。是以,在上面的例子裡,如果你改變模闆參數的聲明順序,那麼調用者就隻需要指定傳回類型:

在這個例子裡,調用max< double >時顯式地把rt指定為double,但其他兩個參數t1和t2可以根據調用實參分别演繹為int和double。

可以看出,所有這些修改後的max()版本都不能得到很大的改進。由于在單(模闆)參數版本裡,如果傳遞進來的是兩個不同類型的實參,你已經可以指定參數的類型(和傳回類型)。是以,盡量保持簡潔并且使用單參數版本的max()就是一個不錯的主意(在接下來的幾節裡,當讨論其他模闆話題的時候,我們将使用這種方法)。

繼續閱讀