日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

C++模板背后的黑箱操作:編譯器

來源: 責編: 時間:2023-12-08 09:14:52 223觀看
導讀一、編譯器如何處理模板1.模板代碼的處理為了理解模板的復雜性,你需要了解編譯器是如何處理模板代碼的。當編譯器遇到模板方法定義時,它會進行語法檢查,但實際上不會編譯模板。編譯器不能編譯模板定義,因為它不知道這些模

一、編譯器如何處理模板

1.模板代碼的處理

為了理解模板的復雜性,你需要了解編譯器是如何處理模板代碼的。當編譯器遇到模板方法定義時,它會進行語法檢查,但實際上不會編譯模板。編譯器不能編譯模板定義,因為它不知道這些模板將用于哪些類型。編譯器不可能為像 x = y 這樣的代碼生成代碼,而不知道 x 和 y 的類型。oRP28資訊網——每日最新資訊28at.com

oRP28資訊網——每日最新資訊28at.com

當編譯器遇到模板的實例化,例如 Grid<int>,它會通過將類模板定義中的每個 T 替換為 int 來為 int 版本的 Grid 模板編寫代碼。當編譯器遇到模板的不同實例化,例如 Grid<SpreadsheetCell>,它會為 SpreadsheetCell 編寫另一個版本的 Grid 類。編譯器只是寫出了如果沒有模板支持,你需要為每種元素類型編寫單獨類時的代碼。這里沒有魔法;模板只是自動化了一個煩人的過程。如果你在程序中沒有為任何類型實例化類模板,那么類方法定義就永遠不會被編譯。oRP28資訊網——每日最新資訊28at.com

這種實例化過程解釋了為什么你需要在定義的各個地方使用 Grid<T> 語法。當編譯器為特定類型(如 int)實例化模板時,它會將 T 替換為 int,使 Grid<int> 成為該類型。oRP28資訊網——每日最新資訊28at.com

2.選擇性實例化

對于隱式類模板實例化,如以下示例:oRP28資訊網——每日最新資訊28at.com

Grid<int> myIntGrid;

編譯器總是為類模板的所有虛擬方法生成代碼。然而,對于非虛擬方法,編譯器只為你實際調用的那些非虛擬方法生成代碼。例如,給定前面的 Grid 類模板,假設你在 main() 中寫了這樣的代碼(僅此代碼):oRP28資訊網——每日最新資訊28at.com

Grid<int> myIntGrid;myIntGrid.at(0, 0) = 10;

編譯器僅為 int 版本的 Grid 生成無參數構造函數、析構函數和非 const 的 at() 方法。它不會生成其他方法,如拷貝構造函數、賦值運算符或 getHeight()。這被稱為選擇性實例化。oRP28資訊網——每日最新資訊28at.com

存在的風險是,某些類模板方法中的編譯錯誤可能會被忽略。未使用的類模板方法可能包含語法錯誤,因為這些不會被編譯。這使得測試所有代碼的語法錯誤變得困難。oRP28資訊網——每日最新資訊28at.com

你可以通過使用顯式模板實例化來強制編譯器為所有方法(虛擬和非虛擬)生成代碼。以下是一個示例:oRP28資訊網——每日最新資訊28at.com

template class Grid<int>;

注意:顯式模板實例化有助于發現錯誤,因為它強制編譯器編譯所有即使未使用的類模板方法。使用顯式模板實例化時,不要只嘗試使用基本類型(如 int)實例化類模板,還要嘗試使用更復雜的類型(如 string)。oRP28資訊網——每日最新資訊28at.com

oRP28資訊網——每日最新資訊28at.com

二、模板對類型的要求

1.類型獨立的代碼編寫

當你編寫與類型無關的代碼時,必須對這些類型做出某些假設。例如,在 Grid 類模板中,你假設元素類型(由 T 表示)是可銷毀的、可拷貝/移動構造的,以及可拷貝/移動賦值的。oRP28資訊網——每日最新資訊28at.com

當編譯器嘗試用不支持類模板方法所使用的所有操作的類型來實例化模板時,代碼將無法編譯,且錯誤消息通常相當晦澀難懂。oRP28資訊網——每日最新資訊28at.com

然而,即使你想使用的類型不支持類模板的所有方法所需的操作,你也可以利用選擇性實例化來使用某些方法而不是其他方法。oRP28資訊網——每日最新資訊28at.com

2.C++20 引入的概念(Concepts)

C++20 引入了概念(concepts),允許你為模板參數編寫編譯器可以解釋和驗證的要求。如果傳遞給模板實例化的模板參數不滿足這些要求,編譯器可以生成更易讀的錯誤消息。后面將討論概念。oRP28資訊網——每日最新資訊28at.com

概念為模板編程增加了額外的類型安全性,它通過為模板參數提供一個明確的接口合約來實現。這種方式不僅可以防止類型不匹配的問題,還可以改善模板錯誤消息的可讀性,從而使模板代碼更容易維護和理解。oRP28資訊網——每日最新資訊28at.com

oRP28資訊網——每日最新資訊28at.com

三、類模板代碼的文件

在類模板中,類模板定義和方法定義必須對任何使用它們的源文件可用。有幾種機制可以實現這一點:oRP28資訊網——每日最新資訊28at.com

1.方法定義與類模板定義在同一文件

你可以將方法定義直接放在定義類模板本身的模塊接口文件中。當你在另一個源文件中導入這個模塊以使用模板時,編譯器將能夠訪問它所需的所有代碼。這種機制用于之前的 Grid 實現。oRP28資訊網——每日最新資訊28at.com

2.方法定義在單獨的文件

或者,你可以將類模板方法定義放在一個單獨的模塊接口分區文件中。然后,你還需要將類模板定義放在自己的分區中。例如,Grid 類模板的主模塊接口文件可能如下所示:oRP28資訊網——每日最新資訊28at.com

export module grid;export import :definition;export import :implementation;

這導入并導出了兩個模塊分區:定義(definition)和實現(implementation)。類模板定義在定義分區中定義:oRP28資訊網——每日最新資訊28at.com

export module grid:definition;import <vector>;import <optional>;export template <typename T> class Grid { ... };

方法的實現位于實現分區中,該分區還需要導入定義分區,因為它需要 Grid 類模板定義:oRP28資訊網——每日最新資訊28at.com

export module grid:implementation;import :definition;import <vector>;...export template <typename T> Grid<T>::Grid(size_t width, size_t height)    : m_width { width }, m_height { height } { ... }

本文鏈接:http://www.www897cc.com/showinfo-26-39515-0.htmlC++模板背后的黑箱操作:編譯器

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: Python入門必備:細講Python推導式

下一篇: 用 print 太慢了!強烈推薦這款 Python Debug 工具

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 大安市| 拜泉县| 永修县| 晋州市| 克拉玛依市| 虞城县| 准格尔旗| 县级市| 出国| 兖州市| 沈阳市| 兴宁市| 辉县市| 邯郸市| 白水县| 绥阳县| 疏附县| 班玛县| 黔西县| 鄂温| 鄂托克旗| 乐业县| 南江县| 青海省| 浦城县| 县级市| 子洲县| 克什克腾旗| 拉萨市| 礼泉县| 揭阳市| 会同县| 克山县| 吴桥县| 剑川县| 海门市| 武乡县| 罗源县| 阿拉尔市| 临安市| 阿瓦提县|