日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

C++ 模板浅谈

發(fā)布時間:2023/12/13 59 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ 模板浅谈 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

引言與概述

C++模板機制允許在定義類,函數(shù),類型別名的時候將類型或值當作參數(shù),這樣定義的類和函數(shù)在運行時間和空間效率上并不遜色于手工打造的非通用的代碼。

模板提供的代碼是類型安全的。

模板是一種編譯時期的機制,與手工編寫的代碼相比,并不會產生任何運行期開銷。

對模板來說,只有當一個成員函數(shù)被使用時才會被生成代碼。

一個通用的組件應該從一個或多個具體實例泛化而來,而不是簡單的從第一原理直接而來。 即我們可以先寫一個具體的函數(shù)或者類,然后改成泛化類型。

模板簡介

一個簡單的模板

template <typename C> class String { public:String();explicit String(const C* c);//..... private:static const int short_max = 15;//用于短字符串的優(yōu)化int sz;C* ptr; };

一個模板類的聲明與普通class的聲明差別不大,只需要添加關鍵字和將需要泛化的類型進行替換。

模板成員函數(shù)也可以不用定義在類內,也可以在外部定義,但模板成員函數(shù)本身還是一個模板,所以要顯式聲明一個模板:

template<typename C> String<C>::String()sz(0),ptr(nullptr) {}

模板實例化

模板實例化:從一個模板和一個模板實參列表生成一個類或者一個函數(shù)的過程。

{String<char> str; }

即可以進行變量的聲明,注意這里我們只創(chuàng)建了對象,即這個類型String< char > 編譯器會為其生成默認構造函數(shù)和析構函數(shù),不使用的成員對象或者函數(shù)則不會生成。

模板提供了一種用少量代碼來生成大量代碼的機制,但我們要小心實例代碼的泛濫,造成內存的大量占用。
通過組合模板和簡單內聯(lián)可以消除很多直接或者間接函數(shù)調用的開銷。

模板參數(shù)

模板機制的最大弱點是無法直接表達對模板參數(shù)的要求。

template <Container Cont, typename Elem>requires Equal_comparable<Cont::value_type, Elem>() int find_index(Cont& c, Elem e);

但我們可以這寫來進行模板參數(shù)的檢查。
在C++20 出現(xiàn)了concept這種技術,可以幫助我們進行對模板參數(shù)要求的檢查。

但這種檢查是在編譯過程中非常晚的時刻進行的,而且是在抽象層次很低的層次上運行的,幫助有限。

成員類型別名

如果我們想要在類外使用模板參數(shù),目前只有使用成員類型別名這種方法:

template <typename C> class String { public:using value_type = T; };

static成員

一個static的成員只有被真正使用時才被定義。

template <typename T> struct X {static int a;static int b; }; int* p = &X<int>::a;

如果這就是全部代碼,那么 a 會被報錯為無定意,而b就不會。

模板與virtual

模板成員函數(shù)不能是虛函數(shù),如果使用那么為虛函數(shù)實現(xiàn)的傳統(tǒng)技巧虛表就很難使用,并且鏈接器的復雜性也會很高。

模板與嵌入類型

在模板中盡量避免嵌入類型,除非它們真正依賴所有的模板參數(shù)。

模板與友元

template <typename T> class B;template <typename T> void A(const B<T>& b);template <typename T> class B { public:friend void A<>(const B<T>& b); };

友元后面的<>是必須的,它指明了友元是一個模板函數(shù),如果沒有<>,則友元函數(shù)被假定為非模板函數(shù)。友元函數(shù)只有被使用時才會被實例化。

友元的設計目的是為了表達一小群緊密相關的概念,如果友元關系很復雜,那么一定是一個設計錯誤。

源碼組織

使用模板組織源碼有三種很明顯的方法:

  • 在一個編譯單元中,在使用模板前包含其定義;
  • 在一個編譯單元中,在使用模板前(只)包含其聲明。在模板稍后的位置(或者使用之后)包含模板定義;
  • 在一個編譯單元中,在使用模板前(只)包含其聲明。在其他編譯單元中包含其定義。

很遺憾的是C++并不支持第三種實現(xiàn)方式。

如果一個類模板的布局或者是一個內聯(lián)函數(shù)模板的定義發(fā)生了改變,那么使用該類或者該函數(shù)的代碼都要重新編譯。

建議

  • 使用模板用于很多實參類型的算法
  • 用模板表示容器
  • 注意template < class T>和template < typename T>意義相同
  • 當設計一個模板時,首先設計和調試非模板版本,隨后添加參數(shù)將其泛化
  • 模板是類型安全的,但檢查的時機太晚了
  • 當設計一個模板時,仔細思考concept,它對模板參數(shù)的要求
  • 如果一個類模板必須是可拷貝的,則為它定義一個非模板的拷貝構造函數(shù)和拷貝復制運算符
  • 如果一個類模板必須是可移動的,則為它定義一個非模板的移動構造函數(shù)和移動復制運算符
  • 虛函數(shù)不能是成員模板函數(shù)
  • 只有當一個類型,依賴類模板的所有實參時才將其定義為模板成員
  • 使用函數(shù)模板推斷類模板實參類型
  • 對多種不同的實參類型,重載函數(shù)模板來獲得相同語義
  • 借助實參帶入失敗機制為程序提供正確的候選函數(shù)集
  • 使用模板別名簡化符號,隱藏實現(xiàn)細節(jié)
  • C++不支持模板分別編譯,在每個用到模板的編譯單元中都#include模板定義
  • 使用普通函數(shù)作為接口編不能用模板處理的代碼
  • 將大的模板和較嚴重依賴上下文的模板分開編譯
  • 沒事的,不論未來如何,太陽一定都會升起!沒事的,不論未來如何,太陽一定都會升起!

    總結

    以上是生活随笔為你收集整理的C++ 模板浅谈的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。