跳至內容

Decltype

出自Taiwan Tongues 台語維基
這是此頁批准,以及是最近的修訂。

佇咧 C + + 程式設計語言內底,decltype做運算子,用佇取得表達式的資料類型。C + + 十一標準引入來 decltype,主要是泛型編程來設計,以解決泛型編程當中有一寡類型由模板參數決定而難以(甚至講無可能)表示的問題。

對語意頂懸講,decltype 的設計適合通用庫編寫者抑是編程新手。總體頂懸講,對變數抑是函式參數作為表達式,由 decltype 推導出的類型佮原始碼內面的定義會當做精準。會當正如 sizeof 運算子仝款,decltype 毋著運算元求值。

簡單理解講

雖然 C + + 規範抑是大多數的文件佮冊攏將 decltype 定義做一个運算子,但是針對初學者來講,應該將這款運算子理解做一種特殊類型聲明,毋是像一寡強型別語言按呢共運算子理解做一个紮倒轉去的函式。為說明此問題,比如講下跤:

對其他語言的開發者,可能寫出如下的代碼:

相反,會當將 decltype 為一種特殊的類型聲明方式,C + + 語言內底類似的功能為自動變數。

舉例:設開發人員無法度確定一个表達式 exp ( ) 的值類型,毋過需要聲明一个佮之類型匹配的變數,會使如下聲明:

decltype ( exp ( ) ) x ;

設計構想

隨著 C + + 引入去模仔,猶閣有由標準模板庫引𤆬的泛型編程漸漸興起來,實現一个會當取得表達式類型的機制的需求就按呢出現,這機制定定叫做 typeof。佇泛型編程當中,若類型由函式參數決定,則知影非常非易事,佇需要取得函式模板實例化的返回類型的時尤然。

為此,誠濟編譯器廠商攏佮程式語言現有的功能,家己實現矣這類運算子,其實現此時 typeof,佮一寡功能有限,毋過更加好徙栽的實現,以滿足這需求。早佇咧 C + + 猶未完全標準化的一九九七年,布萊恩 ・ 帕克(Brian Parker)就是對 sizeof 運算子,提出一種會當移植的解決方案。對這來,比爾 ・ 吉本斯(Bill Gibbons)愛提出,這一方案猶原有真濟限制,而且通常來講,直接引入 typeof 機制效果攏愈好。二空空空年十月,安德烈 ・ 亞歷山德雷斯庫佇咧 IT 技術雜誌《Dr . Dobb's Journal》上評論道:「(若是)有 typeof(運算子), 撰寫佮理解的模板代碼就會方便濟濟。」伊嘛講著「typeof 和 sizeof(運算子)有仝款的後端,(這是)因為乎 sizeof 毋管按怎著愛去做類型。」安德魯 ・ 克尼格佮芭芭拉 ・ E ・ 摩(Barbara E . Moo)嘛講著內底建佇咧程式語言內底的 typeof 功能是非常的有路用,毋過嘛提醒道「使用不時會引入一寡誠歹發覺的程式錯誤,而且閣無法度解決的問題(即並毋是萬用)。」並且提出會當利用類型轉換(如使用標準模板庫所提供的 typedef), 閣較有效、閣較通用實現這一个功能。猶毋過,史蒂夫 ・ 丹斯特(Steve Dewhurst)是按呢轉換「佇設計佮發布上開足大的」,而且「採用直接提表達式類型的方法閣較簡單」(大意)。 二空一一年的時間,佇一片關於著 C + + 零 x 的文章當中,克尼格佮摩預言道:「 decltype 會廣泛用佇每日的程式編寫提供便利。」

二空空二年間,比雅尼 ・ 史特勞斯特魯普提議擴充 C + + 程式語言,為之引入查詢表達式類型,猶閣有毋免指明類型便可初化物件的機制。史特勞斯特魯普注意著,佇咧 GCC 佮 EDG 編譯器當中,typeof 所提供的「參照擲捒」(reference-dropping)語意可能存在問題;另外一方面,你若表達式左值性、倒轉一个參照類型的運算子實現之,閣歹理解。所以,咧呈交予 C + + 標準委員會初初的提案中,就共兩種實現方法雜配起來:干焦做表達式的聲明類型包括一个參照的時陣,運算子才會返回一个參照類型。為強調推導出的類型能確實反映表達式的聲明類型,提案中提議欲按呢運算子號名做 decltype。提案猶閣提供 decltype 的一項主要設計初衷,嘛隨予編寫完美的轉發函式成做可能。咧編程的時,程式設計師若有當時仔需要編寫一个泛型轉發函式,使之不論以何種類型實例化,攏會當回倒轉和包裝函式的類型,若無 decltype 運算子,就差不多無可能做甲這點。decltype 的款像代碼如下所示,其中利用了 C + + 十一標準中的「返回類型後置」(trailing-return-type)語法。

decltype 就是本段代碼的核心的部份,用於儲存「包裝函式敢是回回一个參照類型」這一个資訊。

語意

類似 sizeof 運算子,decltype 毋著其運算元求值。粗略來講,decltype ( e ) 倒轉來類型進前,進行矣如下推導:

  • 若表達式 e 為一个無括號的變數、函式參數、類別成員來儉定,遐爾仔倒轉去類型即為該變數抑是參數抑是類別成員佇源站內底的「聲明類型」;
  • 若無,根據表達式的值分類(value categories), 設 T 為 e 的類型:
  • 若是 e 是一个左值(lvalue,即「會當定址值」), 著 decltype ( e ) 共返回 T &;
  • 若是 e 是一个臨終值(xvalue), 愛轉去回值為 T & &;
  • 若是 e 是一个純右值(prvalue), 愛轉去回值為 T。

這語意是為滿足通用庫編寫者的需求而設計,毋過因為 decltype 伊轉去類型總和物件(抑是函式)的定義類型相匹配,這對編程新手來講嘛較直觀。閣較正式來講,規則一適用佇無帶括號的識別碼表達式(id-expression)佮類別成員存取表達式。範譬如講下:

由上可見,最後兩个著 decltype 的呼叫,倒轉來結果有無仝款。這是因為,帶括號的表達式 ( a-> x ) 既非「識別碼表達式」,亦非類存取表達式,因為無指向一个號名物件,是一个左值,就算講推導類型便為「指向表達式類型的參照」,亦即 const double &。

佇二空空八年十二月,雅克 ・ 雅爾維(Jaakko Järvi)向標準委員會指出一个問題:佇咧 C + + 中,「 紮限定識別碼」(qualified-id)無法度由 decltype 作成,這个正港「decltype ( e ) 可作『類型的定義名』(typedef-name)看待」的設計初衷無一致。佇咧評論標準的委員會為 C + + 零 x(C + + 十一前名)制定的正式的草案的時陣,日本 ISO 會員成員講著,「 一个定義域運算子(: :)無適用著 decltype,但有本應用才著。(若會當解決這个問題,著)這佇需要對實例中取得成員類型(岫狀類型)足有路用的,如下所示」:

這一問題,以及其他相仝問題(關於著 decltype 無法度佇衍生類聲明佮解構函式呼叫中使用), 攏交予大衛 ・ 范德沃德(David Vandevoorde)處理,並且佇二空一空年三月投票納入工作日程表。解決辦法是:若表達式是純使用者定義類型(plain user defined type), 就毋是參照、指標、函式等,著 decltype 表達式返回類名。這意味會當存取岫狀類型。甚至會當用啦 ` decltype ( expr ) ` 做衍生的時陣的基本類型。

可用性

decltype 包含著當前的 C + + 標準 C + + 十一中,並且由真濟編譯器以擴充的形式提供:軟軟仔佇咧 Visual C + + 二千空一十編譯器當中提供矣 decltype 運算子,基本實現囉標準委員會提案中所來描述的語意,並且佇代管代碼抑是原生代碼中攏會當使用。照其文件講,這一實現「主要對編寫模板庫的開發者有用。」二空空八年三月初五發布的四四配三版開始,GCC C + + 編譯器嘛加入去矣 decltype 運算子。這運算子嘛納入矣 Codegear 的 C + + Builder 二千空九、Intel C + + 編譯器佮 Clang。

注釋

參考資料

外部連結

  • 比雅尼 ・ 史特勞斯特魯普的「C + + 十一 FAQ」中關於 decltype 的部份