C++模板的介紹

2021-01-07 酷扯兒

本文轉載自【微信公眾號:羽林君,ID:Conscience_Remains】經微信公眾號授權轉載,如需轉載與原文作者聯繫

1. 模板是泛型編程的基礎,泛型編程即以一種獨立於任何特定類型的方式編寫代碼。C++模板的作用,類似於C中的typedef,不過C++中模板有更多的靈活性。C++模板類型,類似於Objective-C中的泛型。C++通過類模板來實現泛型支持。

2.C++中有兩種模板,分別是函數模板和類模板。

一、類模板

當程序有出現有一些相似的類,這個時候我們可以選擇使用類模板進行定義,但是與函數模板不同,類模板不能推斷實例化(下面有描述推斷的情況),所以你只能顯示執行類型參數使用Printer<int> p(1),而不能讓編譯器自行推斷Printer p(1)。

示例代碼部分

template<typename T> 標誌:

T T 可以替換為我們需要的變量類型:例如 int double等

template<typename T>

class AAA{

private:

T t;

public:

void test_func(const T &t);

void print(void);

};

template<typename T>

void AAA<T>::test_func(const T&t)

{

this->t = t;

}

template<typename T>

void AAA<T>::print(void)

{

cout<<t<<endl;

}

使用介紹

1:用時再實例化

AAA<int>a;

AAA<double>b;

2:事先實例化

/*事先實例化*/

template AAA<int>

/*再使用*/

AAA<int >a;

類的定做與繼承

函數模板可以重載,類模板也可以進行重載,這樣的類叫做定做。

定義好<>裡面的類型之後,類裡面所有的成員都可以修改,而派生類可以與之前不一樣。

在模板類的繼承中,需要注意以下三點:如果父類自定義了構造函數,記得子類要使用構造函數列表來初始化繼承的時候,如果子類不是模板類,則必須指明當前的父類的類型,因為要分配內存空間 繼承的時候,如果子類是模板類,要麼指定父類的類型,要麼用子類的泛型來指定父類

template<>

class AAA<int>{

public:

void test_func_int(const int &t)

{

cout<<t<<endl;

}

void print(void);

};

void AAA<int>::print(void)

{

cout<<"for test"<<endl;

}

二、函數模板

函數模板:函數重載實現相同函數名的實現,但是如果有很多種實現類型框架需要實現,我們便不可以重複的寫如此多的重載函數,我們需要函數模板去實現,在重載函數使用不同的參數類型作為一個參數定義一個函數,這便是函數模板的初始定義。

函數模板實例化

函數模板只是一套編譯指令,一般寫在頭文件.編譯程序的時候,編譯器根據函數的參數來推導生成 模板的函數,類似Makefile規則.

通過模板得到函數的過程,我們稱之為模板的實例化或者叫模板的具體化.

示例代碼

using namespace std;

template<typename T>

const T& mymax(const T& a,const T& b)

{

// cout<<"mymax(T& a,T& b)"<<endl;

cout<<__PRETTY_FUNCTION__<<endl;

return (a<b)?b:a;

}

template<typename T>

const T * mymax1(const T* a,const T* b)

{

// cout<<"mymax(T& a,T& b)"<<endl;

cout<<__PRETTY_FUNCTION__<<endl;

return (a<b)?b:a;

}

template<typename T>

void test_func(T f)

{

cout<<__PRETTY_FUNCTION__<<endl;

}

int f1(int a,int b)

{

return 0;

}

void add(int a,int b)

{

cout<<"add(int a,int b) ="<<(a+b)<<endl;/*普通函數可以進行簡單的隱式類型轉化*/

}

int main(int argc,char** argv)

{

int a = 1,b = 2.1;

add(a,b);/*隱式轉化,但是函數模板不支持此種轉化*/

int ia = 1, ib = 2;

mymax(ia,ib);/*隱式轉化支持從可讀寫轉為只讀 ,從高到低*/

char ca[] = "ab";

char cb[] = "cd";

mymax(ca,cb);

mymax1(ca,cb);/*s數組轉化為指針*/

char ca1[] = "abc";/*長度不一致的時候 error*/

char cb1[] = "cd";

// mymax(ca1,cb1);/*無法推導出同樣的T char&[3],char&[2]*/

mymax1(ca1,cb1);/*s數組轉化為指針*/

test_func(f1);

test_func(&f1);

return 0;

}

在匹配函數之後,發現有出現匹配度相同的函數,優先選擇普通函數。對於多個模板函數,選擇「更特化」函數,否則出現二義性錯誤。

函數模板使用的時候注意調用使用的順序規則。最特化:更特殊、更具體、更細化。

相關焦點

  • C++機器學習庫介紹
    介紹我喜歡使用C++。C++是我學習過的第一種程式語言,我喜歡在機器學習中使用它。我在之前寫過關於構建機器學習模型的文章。我收到了一個回復,問我C++有沒有機器學習的庫?這是個公平的問題。像Python和R這樣的語言有大量的包和庫來滿足不同的機器學習任務。
  • c++11新特性,所有知識點都在這了!
    本文基本上涵蓋了c++11的所有新特性,並有詳細代碼介紹其用法,對關鍵知識點做了深入分析,對重要的知識點我單獨寫了相關文章並附上了相關連結,我整理了完備的c++新特性腦圖(由於圖片太大,我沒有放在文章裡,同學可以在後臺回復消息「新特性」,即可下載完整圖片)。
  • 跟我學C++中級篇——STL的學習
    一、c++標準庫C++的標準庫主要包含兩大類,首先是包含C的標準庫的,當然,為了適應c++對一些C庫進行了少許的修改和增加。最重要的當然是面向對象的c++庫;而c++庫又可以分成兩大類,即面向對象的c++庫和標準模板庫,也就是題目中的STL。
  • C++機器學習庫介紹 | 文末送書
    介紹我喜歡使用C++。
  • C++ initializer_list 詳解
    initializer_list是C++11中新增的,用於可讓我們列表初始化容器,自定義的函數,自定義的類中的構造函數,要在代碼中使用initializer_list必須包含頭文件initializer_list,這個模板很簡單,包含成員函數 begin(),end(),size(),可以使用這些函數去遍歷列表元素。
  • C++14新特性的所有知識點全在這兒啦!
    前面程序喵介紹過C++11的新特性,這篇文章介紹下C++14的新特性。
  • C++typename的由來和用法
    這個關鍵字用於指出模板聲明(或定義)中的非獨立名稱(dependent names)是類型名,而非變量名。我們經常會這麼用 typename,這是一項C++程式語言的泛型編程(或曰「模板編程」)的功能,typename關鍵字用於引入一個模板參數。
  • 【C++】數據類型
    今天來講講不c++中同數據類型的使用方法和區別1.基礎類型類型範圍內存中佔的大小char-128~127或0~2551byteunsigned
  • C++ 優先隊列priority_queue
    結構定義優先隊列的結構定義是一個模板類,需要提供三個類型參數:template< class T, class Container = std::vector<T>, class Compare = std::less<typename Container::value_type
  • 九大程式語言優缺點第四期:c++
    上一期給大家介紹了C語言,理所應當的本期給大家了解下C語言的超集,c++那麼接下來給大家介紹主流程式語言:C++、JavaScript、C#、Ruby、PHP以及Objective-C,對於這幾種語言,大家都能看到由其打造的頂尖應用,我們一起來了解一下吧。
  • C++ Primer Plus中文版(第4、5、6版)
    以下是第五版的介紹,4和6版略C++是在C語言基礎上開發的一種集面向對象編程、通用編程和傳統的過程化編程於一體的程式語言
  • C++ vector詳解
    以下是正文前言本文mark了vector的一些接口,介紹了vector中的對內存和對象的管理詳解請見cppreference-vector。7. emplace()相當於insert(),但是其通過參數包和模板偏特化減少了一次拷貝構造的過程。
  • C++基礎總結(一):從「hello world」入門C++!
    面向對象程序設計c++最大的亮點就是面向對象程序設計理念的運用。包括面向對象開發的四大特性:封裝;抽象;繼承;多態C++的組成部分標準的 C++ 由三個重要部分組成:核心語言,提供了所有構件塊,包括變量、數據類型和常量,等等。
  • C++模板之SFINAE和enable_if分析
    (給CPP開發者加星標,提升C/C++技能)https://blog.csdn.net/xiangbaohui/article/details/106575509【導讀】:本文主要介紹SFINAESFINAE是"Substitution failure is not an error"(替換失敗不是錯誤),官方給的解釋為:在函數模板的重載決議中:為模板形參替換推導類型失敗時,從重載集拋棄特化,而非導致編譯錯誤。用一句簡單的話來說,C++在編譯的時候,模板實例化的時候就算實例化失敗也不會出現錯誤。
  • 編譯器 | 五款好用的C/C++編譯器(IDE利器)
    3 Code Blockscode block 是最流行的免費開源的集成環境之一,這是一個追求跨平臺的編譯器,除了調試功能和 dev-c++ 的使用情況有點不同,其餘的它也都包含,除此之外,codeblocks擴展性能非常強大,也提供了很多工程模板,軟體內置大量的開發插件程序,你可以直接在軟體中進行連接下載,幫助您獲得更高效、穩定、快捷的開發輔助程序,codeblocks新版在項目構建。(編譯器獲取方式在文末)
  • c++的輸入與輸出
    c++輸入與輸出C++ 標準庫提供了一組豐富的輸入/輸出功能,本章將討論 C++ 編程中最基本和最常見的 I/O 操作。輸入輸出並不是c++語言的正式組成成分,c和c++沒有為輸入輸出提供專門的結構。在c語言中輸入輸出是通過調用scanf和printf 實現的,在c++中是通過調用流對象cin和cout實現的。
  • C++模板進階指南:SFINAE
    以下是正文SFINAE可以說是C++模板進階的門檻之一,如果選擇一個論題來測試對C++模板機制的熟悉程度,那麼在我這裡,首選就應當是SFINAE機制。我們不用糾結這個詞的發音,它來自於 Substitution failure is not an error 的首字母縮寫。
  • C++、java 和 C 的區別
    一、基礎類型c++:** java:** C#:1.以java為準,c++裡面的int short long 像這樣的整型 一般都有unsigned 和signed的區分 ,這個跟java和c# 的區別比較大,但c#裡面有unit ulong ushort 這三種就相當於c++的修飾詞unsigned,當c++李明的變量類型定義unsigned,就默認是整數。
  • C++類與回調函數
    另外,如果想要採用這種方法實現回調,那麼在定義回調函數的時候就得知道誰會調用它,顯然,這個要求是不合理的,所以,這種方法很不常用,只是介紹這種方法。function模板首先介紹一下什麼叫可調用對象,簡單來說就是可以使用()來調用的對象,在C++11中,包括函數、函數指針、lambda表達式、bind創建的對象和重載了()的類。
  • 零基礎入門C++到進騰訊,你還差這份開源寶典
    第2部分是實戰系列,這部分內容實操性就比較強了,創建者稱之為10日狂練,每天的練習內容如下:day1:基本c++語法day2:遞歸、結構體、枚舉靜態變量等day3:函數day4:函數深入day5:繼承多態day6:虛函數、抽象類day7:運算符重載day8:模板與