首頁 > 軟體

C++超詳細講解模板的使用

2022-06-17 14:03:09

一、函數模板

1.1函數模板概念

函數模板代表了一個函數家族,該函數模板與型別無關,在使用時被引數化,根據實參型別產生函數的特定型別版本。

1.2 函數模板格式

template<typename T1, typename T2,…,typename Tn>

返回值型別 函數名(參數列){}

template<class T>
void swap(T& a, T& b)
{
	T tmp = a;
	a = b;
	b = tmp;
}

注意:typename是用來定義模板引數關鍵字,也可以使用class(切記:不能使用struct代替class)

1.3 函數模板的原理

函數模板是一個藍圖,它本身並不是函數,是編譯器用使用方式產生特定具體型別函數的模具。所以其實模板就是將本來應該我們做的重複的事情交給了編譯器

在編譯器編譯階段,對於模板函數的使用,編譯器需要根據傳入的實參型別來推演生成對應型別的函數以供呼叫。比如:當用double型別使用函數模板時,編譯器通過對實參型別的推演,將T確定為double型別,然後產生一份專門處理double型別的程式碼,對於字元型別也是如此。

1.4 函數模板的範例化

用不同型別的引數使用函數模板時,稱為函數模板的範例化。模板引數範例化分為:隱式範例化和顯式範例化

隱式範例化:讓編譯器根據實參推演模板引數的實際型別

template<class T>
T Add(const T& left, const T& right)
{
  return left + right;
}
int main()
{
  int a1 = 10, a2 = 20;
  double d1 = 10.0, d2 = 20.0;
  Add(a1, a2);
  Add(d1, d2);
  /*
  該語句不能通過編譯,因為在編譯期間,當編譯器看到該範例化時,需要推演其實參型別
  通過實參a1將T推演為int,通過實參d1將T推演為double型別,但模板參數列中只有
一個T,
  編譯器無法確定此處到底該將T確定為int 或者 double型別而報錯
  注意:在模板中,編譯器一般不會進行型別轉換操作,因為一旦轉化出問題,編譯器就需要
背黑鍋
  Add(a1, d1);
  */
  // 此時有兩種處理方式:1. 使用者自己來強制轉化 2. 使用顯式範例化
  Add(a, (int)d);
  return 0;
}

顯式範例化:在函數名後的<>中指定模板引數的實際型別

int main(void)
{
  int a = 10;
  double b = 20.0;
  // 顯式範例化
  Add<int>(a, b);
  return 0;
}

如果型別不匹配,編譯器會嘗試進行隱式型別轉換,如果無法轉換成功編譯器將會報錯。

二、類別範本

2.1 類別範本的定義格式

template<class T1, class T2, ..., class Tn>
class 類別範本名
{
// 類內成員定義
};  
// 動態順序表
// 注意:Vector不是具體的類,是編譯器根據被範例化的型別生成具體類的模具
template<class T>
class Vector
{
public :
Vector(size_t capacity = 10)
: _pData(new T[capacity])
  , _size(0)
  , _capacity(capacity)
{}
// 使用解構函式演示:在類中宣告,在類外定義。
~Vector();
void PushBack(const T& data);
void PopBack();
// ...
size_t Size() {return _size;}
T& operator[](size_t pos)
{
  assert(pos < _size);
  return _pData[pos];
}
private:
T* _pData;
size_t _size;
size_t _capacity;
};
// 注意:類別範本中函數放在類外進行定義時,需要加模板參數列
template <class T>
Vector<T>::~Vector()
{
if(_pData)
  delete[] _pData;
_size = _capacity = 0;
}

2.2類別範本的範例化

類別範本範例化與函數模板範例化不同,類別範本範例化需要在類別範本名字後跟<>,然後將範例化的型別放在<>中即可,類別範本名字不是真正的類,而範例化的結果才是真正的類。

// Vector類名,Vector<int>才是型別
Vector<int> s1;
Vector<double> s2;

總結

以上就是關於模板的初階全部內容,後續還會更新,感謝大家的觀看

到此這篇關於C++超詳細講解模板的使用的文章就介紹到這了,更多相關C++模板內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com