新聞中心
一、編譯器如何處理模板
1.模板代碼的處理
為了理解模板的復(fù)雜性,你需要了解編譯器是如何處理模板代碼的。當(dāng)編譯器遇到模板方法定義時(shí),它會進(jìn)行語法檢查,但實(shí)際上不會編譯模板。編譯器不能編譯模板定義,因?yàn)樗恢肋@些模板將用于哪些類型。編譯器不可能為像 x = y 這樣的代碼生成代碼,而不知道 x 和 y 的類型。

創(chuàng)新互聯(lián)建站專注于呼瑪企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè)公司,商城系統(tǒng)網(wǎng)站開發(fā)。呼瑪網(wǎng)站建設(shè)公司,為呼瑪?shù)鹊貐^(qū)提供建站服務(wù)。全流程按需定制制作,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)建站專業(yè)和態(tài)度為您提供的服務(wù)
當(dāng)編譯器遇到模板的實(shí)例化,例如 Grid
這種實(shí)例化過程解釋了為什么你需要在定義的各個(gè)地方使用 Grid
2.選擇性實(shí)例化
對于隱式類模板實(shí)例化,如以下示例:
Grid myIntGrid; 編譯器總是為類模板的所有虛擬方法生成代碼。然而,對于非虛擬方法,編譯器只為你實(shí)際調(diào)用的那些非虛擬方法生成代碼。例如,給定前面的 Grid 類模板,假設(shè)你在 main() 中寫了這樣的代碼(僅此代碼):
Grid myIntGrid;
myIntGrid.at(0, 0) = 10; 編譯器僅為 int 版本的 Grid 生成無參數(shù)構(gòu)造函數(shù)、析構(gòu)函數(shù)和非 const 的 at() 方法。它不會生成其他方法,如拷貝構(gòu)造函數(shù)、賦值運(yùn)算符或 getHeight()。這被稱為選擇性實(shí)例化。
存在的風(fēng)險(xiǎn)是,某些類模板方法中的編譯錯(cuò)誤可能會被忽略。未使用的類模板方法可能包含語法錯(cuò)誤,因?yàn)檫@些不會被編譯。這使得測試所有代碼的語法錯(cuò)誤變得困難。
你可以通過使用顯式模板實(shí)例化來強(qiáng)制編譯器為所有方法(虛擬和非虛擬)生成代碼。以下是一個(gè)示例:
template class Grid; 注意:顯式模板實(shí)例化有助于發(fā)現(xiàn)錯(cuò)誤,因?yàn)樗鼜?qiáng)制編譯器編譯所有即使未使用的類模板方法。使用顯式模板實(shí)例化時(shí),不要只嘗試使用基本類型(如 int)實(shí)例化類模板,還要嘗試使用更復(fù)雜的類型(如 string)。
二、模板對類型的要求
1.類型獨(dú)立的代碼編寫
當(dāng)你編寫與類型無關(guān)的代碼時(shí),必須對這些類型做出某些假設(shè)。例如,在 Grid 類模板中,你假設(shè)元素類型(由 T 表示)是可銷毀的、可拷貝/移動構(gòu)造的,以及可拷貝/移動賦值的。
當(dāng)編譯器嘗試用不支持類模板方法所使用的所有操作的類型來實(shí)例化模板時(shí),代碼將無法編譯,且錯(cuò)誤消息通常相當(dāng)晦澀難懂。
然而,即使你想使用的類型不支持類模板的所有方法所需的操作,你也可以利用選擇性實(shí)例化來使用某些方法而不是其他方法。
2.C++20 引入的概念(Concepts)
C++20 引入了概念(concepts),允許你為模板參數(shù)編寫編譯器可以解釋和驗(yàn)證的要求。如果傳遞給模板實(shí)例化的模板參數(shù)不滿足這些要求,編譯器可以生成更易讀的錯(cuò)誤消息。后面將討論概念。
概念為模板編程增加了額外的類型安全性,它通過為模板參數(shù)提供一個(gè)明確的接口合約來實(shí)現(xiàn)。這種方式不僅可以防止類型不匹配的問題,還可以改善模板錯(cuò)誤消息的可讀性,從而使模板代碼更容易維護(hù)和理解。
三、類模板代碼的文件
在類模板中,類模板定義和方法定義必須對任何使用它們的源文件可用。有幾種機(jī)制可以實(shí)現(xiàn)這一點(diǎn):
1.方法定義與類模板定義在同一文件
你可以將方法定義直接放在定義類模板本身的模塊接口文件中。當(dāng)你在另一個(gè)源文件中導(dǎo)入這個(gè)模塊以使用模板時(shí),編譯器將能夠訪問它所需的所有代碼。這種機(jī)制用于之前的 Grid 實(shí)現(xiàn)。
2.方法定義在單獨(dú)的文件
或者,你可以將類模板方法定義放在一個(gè)單獨(dú)的模塊接口分區(qū)文件中。然后,你還需要將類模板定義放在自己的分區(qū)中。例如,Grid 類模板的主模塊接口文件可能如下所示:
export module grid;
export import :definition;
export import :implementation;這導(dǎo)入并導(dǎo)出了兩個(gè)模塊分區(qū):定義(definition)和實(shí)現(xiàn)(implementation)。類模板定義在定義分區(qū)中定義:
export module grid:definition;
import ;
import ;
export template class Grid { ... }; 方法的實(shí)現(xiàn)位于實(shí)現(xiàn)分區(qū)中,該分區(qū)還需要導(dǎo)入定義分區(qū),因?yàn)樗枰?nbsp;Grid 類模板定義:
export module grid:implementation;
import :definition;
import ;
...
export template Grid::Grid(size_t width, size_t height)
: m_width { width }, m_height { height } { ... } 網(wǎng)頁名稱:C++模板背后的黑箱操作:編譯器
URL地址:http://m.fisionsoft.com.cn/article/djhhjds.html


咨詢
建站咨詢
