国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C++中的泛型詳細(xì)講解

這篇具有很好參考價(jià)值的文章主要介紹了C++中的泛型詳細(xì)講解。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

1.定義

它是一種泛化的編程方式,其實(shí)現(xiàn)原理為程序員編寫(xiě)一個(gè)函數(shù)/類(lèi)的代碼示例,讓編譯器去填補(bǔ)出不同的函數(shù)實(shí)現(xiàn)。允許您延遲編寫(xiě)類(lèi)或方法中的編程元素的數(shù)據(jù)類(lèi)型的規(guī)范,直到實(shí)際在程序中使用它的時(shí)候。換句話(huà)說(shuō),泛型允許您編寫(xiě)一個(gè)可以與任何數(shù)據(jù)類(lèi)型一起工作的類(lèi)或方法。

2.模板

模板是泛型編程的基礎(chǔ),是創(chuàng)建泛型類(lèi)或函數(shù)的藍(lán)圖或公式。庫(kù)容器,比如迭代器和算法,都是泛型編程的例子,它們都使用了模板的概念。每個(gè)容器都有一個(gè)單一的定義,比如 向量,我們可以定義許多不同類(lèi)型的向量,比如 vector vector 。可以使用模板來(lái)定義函數(shù)和類(lèi),我們來(lái)具體分析一下模板函數(shù)和模板類(lèi)的創(chuàng)建和使用:

2.1 模板函數(shù)

我們想實(shí)現(xiàn)像Python一樣,一個(gè)帶有參數(shù)的方法,它的相同參數(shù)可以傳遞不同類(lèi)型的值。我們通過(guò)下面的例子來(lái)了解一下:

#include<iostream>
using namespace std;

template<typename T>
void Test(T& arg1,T& arg2) // 這是一個(gè)實(shí)現(xiàn)兩個(gè)變量值交換的函數(shù)
{
    T temp = arg1;
    arg1 = arg2;
    arg2 = temp;
}
// typename 是定義模板的關(guān)鍵字,可以用class來(lái)替代(注意不能用struct)
int main()
{
    int a = 10, b = 20;
    double c = 5.2, d = 10.5;
    Test(a, b);
    Test(c, d);
    cout << a << " " << b << endl;
    cout << c << " " << d << endl;
}
// 輸出結(jié)果:
20 10
10.5 5.2

// 我們交換了int類(lèi)型的a與b的值,double類(lèi)型c和d的值

如果我們將int和double同時(shí)傳給Swap這個(gè)函數(shù),那么編譯器會(huì)報(bào)錯(cuò),表示模板參數(shù)T不明確,那么我們需要做如下改動(dòng):

(1)把函數(shù)傳參中的引用去掉

(2)把a(bǔ)強(qiáng)制轉(zhuǎn)換成double類(lèi)型,Swap((double)a, c)

#include<iostream>
using namespace std;

template<typename T>
void Test(T arg1,T arg2) // 把“&”引用去掉
{
    T temp = arg1;
    arg1 = arg2;
    arg2 = temp;
    cout << arg1 << " " << arg2 << endl;
}

int main()
{
    int a = 10;
    double c = 5.2;

    Test((double)a, c);
    cout << "a:" << a << " c:" << c << endl;
}

// 輸出結(jié)果:
5.2 10
a:10 c:5.2
// a,c值沒(méi)有變,是因?yàn)槲覀儌鲄⑹侵祩鬟f

接下來(lái)我們看一下,多個(gè)模板參數(shù)的情況:

#include<iostream>
#include<typeinfo>
using namespace std;

template<typename T1, typename T2>
void Info(T1 arg1,T2 arg2)
{
    cout << typeid(arg1).name() << endl;
    cout << typeid(arg2).name() << endl;
}

int main()
{
    int a = 10;
    double c = 5.2;

    Info(a, c);
    cout << "a:" << a << " c:" << c << endl;
}

// 輸出結(jié)果:
i
d
a:10 c:5.2

可以看到,實(shí)際上函數(shù)在調(diào)用這個(gè)模板的時(shí)候,已經(jīng)實(shí)例化了這個(gè)函數(shù)(即替換模板參數(shù)為正確參數(shù)類(lèi)型)這時(shí)候在后臺(tái)處理的時(shí)候,其實(shí)Show函數(shù)已經(jīng)實(shí)例化為了下面這個(gè)樣子

void Info(int arg1,double arg2)
{
    cout << typeid(arg1).name() << endl;
    cout << typeid(arg2).name() << endl;
}

2.2 函數(shù)模板實(shí)例化

上面的方式,是編譯器自動(dòng)幫我們實(shí)例化模板參數(shù)。在實(shí)際使用中,我們還可以自己指定實(shí)例化為什么類(lèi)型

  • 利用強(qiáng)制類(lèi)型轉(zhuǎn)換
  • 使用<int>直接指定實(shí)例化為int類(lèi)型
#include<iostream>
using namespace std;

template<typename T>
void Test(T arg1,T arg2) // 把“&”引用去掉
{
    T temp = arg1;
    arg1 = arg2;
    arg2 = temp;
    cout << arg1 << " " << arg2 << endl;
}

int main()
{
    int a = 10;
    double c = 5.2;

    Test((double)a, c);    // 強(qiáng)制類(lèi)型轉(zhuǎn)換
    Test<int>(a, c);        // 直接指定
    cout << "a:" << a << " c:" << c << endl;
}
/*
使用第二種方式的時(shí)候,編譯器會(huì)對(duì)另外一個(gè)不匹配的參數(shù)進(jìn)行隱式類(lèi)型轉(zhuǎn)換。如果轉(zhuǎn)換不成功,則會(huì)報(bào)錯(cuò)。

另外注意的是,函數(shù)模板參數(shù)T同樣可以用來(lái)作為返回值,但是不能通過(guò)返回值來(lái)推斷參數(shù)T的類(lèi)型。比如下面這個(gè)函數(shù),我們?cè)谑褂玫臅r(shí)候就需要直接指定模板參數(shù)T,而不能寫(xiě)一個(gè)int* ptr=test(10)讓編譯器通過(guò)“返回值是int*接收的,所以函數(shù)模板參數(shù)T是int”來(lái)推斷。
*/

2.3 函數(shù)模板實(shí)例化

函數(shù)模板支持給予參數(shù)缺省值,當(dāng)一個(gè)參數(shù)不確定的時(shí)候,函數(shù)模板是支持給予缺省值的

template<typename T=char>
T* Test(int num)
{
	return new T[num];
}

當(dāng)有多個(gè)模板參數(shù)時(shí),缺省值需要從右往左給,當(dāng)然函數(shù)模板的傳參也支持缺省值:

#include<iostream>
using namespace std;

template<typename T>
void Test(T arg1,T arg2=20) // 把“&”引用去掉
{
    T temp = arg1;
    arg1 = arg2;
    arg2 = temp;
    cout << arg1 << " " << arg2 << endl;
}

int main()
{
    int a = 10;

    Test(a);
}

2.4 模板函數(shù)與普通函數(shù)同時(shí)存在情況

函數(shù)在調(diào)用的時(shí)候,首先會(huì)去調(diào)用已經(jīng)存在的函數(shù)。當(dāng)參數(shù)和已存在的函數(shù)不匹配時(shí),才會(huì)調(diào)用函數(shù)模板

#include<iostream>
using namespace std;

template<typename T>
void Test(T arg1,T arg2 = 90) 
{
    cout << "Test temp " << arg1 << " " << arg2 << endl;
}

void Test(int arg1,int arg2) 
{
   	cout << "Test " << arg1 << " " << arg2 << endl;
}

int main()
{
    int a = 10, b = 20;
    double c = 5.2, d = 10.5;

    Test(a);
    Test(a, b);
    Test(a, (int)c);    // 強(qiáng)轉(zhuǎn)
    Test((double)a, c); // 強(qiáng)轉(zhuǎn)
    Test<int>(a, c);    // 直接指定為int
}
// 輸出結(jié)果:
Test temp 10 90
Test 10 20
Test 10 5
Test temp 10 5.2
Test temp 10 5

2.5 函數(shù)模板不支持定義和聲明分離

函數(shù)模板的聲明和定義要放在一個(gè)頭文件中。在部分使用場(chǎng)景,會(huì)使用.hpp來(lái)表示這個(gè)頭文件是包含了函數(shù)定義的(即.h和.cpp的集合體)。需要注意,這并不是一個(gè)硬性要求,你也可以直接使用.h,并將聲明和定義放入其中。因?yàn)閱为?dú)的.h聲明會(huì)在源文件頂部展開(kāi),而此時(shí)函數(shù)模板正常推演參數(shù),但編譯器并沒(méi)有找到函數(shù)的實(shí)現(xiàn),即這是一個(gè)沒(méi)有地址的函數(shù)。從而導(dǎo)致編譯器找不到函數(shù)的地址,產(chǎn)生了符號(hào)表的鏈接錯(cuò)誤。其實(shí)是有的,我們可以在模板函數(shù)定義的.cpp中對(duì)我們需要使用的函數(shù)進(jìn)行顯式實(shí)例化指定

//頭文件
//聲明
template<typename T>
void Test(T arg1, T arg2);
//源文件
//定義
template<typename T>
void Test(T arg1, T arg2)
{
   cout << arg1 << " " << arg2 << endl;
}
//在源文件中顯式實(shí)例化
template
void Test<int>(int arg1, int arg2);
template
void Test<double>(double arg1, double arg2);

顯式實(shí)例化需要對(duì)我們要用的所有函數(shù)進(jìn)行實(shí)例化,比如你需要用double類(lèi)型,只顯示實(shí)例化了int類(lèi)型是不行的,依舊會(huì)報(bào)錯(cuò)。這樣感覺(jué)非常多余……!所以還是把聲明和定義放在同一個(gè)文件里面清晰明了一些。

3 類(lèi)模板

正如我們定義函數(shù)模板一樣,我們也可以定義類(lèi)模板。泛型類(lèi)聲明的一般形式如下所示:

template <class type> class class-name {
.
.
.
}

在這里,type 是占位符類(lèi)型名稱(chēng),可以在類(lèi)被實(shí)例化的時(shí)候進(jìn)行指定。您可以使用一個(gè)逗號(hào)分隔的列表來(lái)定義多個(gè)泛型數(shù)據(jù)類(lèi)型。

下面的實(shí)例定義了類(lèi) Stack<>,并實(shí)現(xiàn)了泛型方法來(lái)對(duì)元素進(jìn)行入棧出棧操作:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-530955.html

#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>
 
using namespace std;
 
template <class T>
class Stack { 
  private: 
    vector<T> elems;     // 元素 
 
  public: 
    void push(T const&);  // 入棧
    void pop();               // 出棧
    T top() const;            // 返回棧頂元素
    bool empty() const{       // 如果為空則返回真。
        return elems.empty(); 
    } 
}; 
 
template <class T>
void Stack<T>::push (T const& elem) 
{ 
    // 追加傳入元素的副本
    elems.push_back(elem);    
} 
 
template <class T>
void Stack<T>::pop () 
{ 
    if (elems.empty()) { 
        throw out_of_range("Stack<>::pop(): empty stack"); 
    }
    // 刪除最后一個(gè)元素
    elems.pop_back();         
} 
 
template <class T>
T Stack<T>::top () const 
{ 
    if (elems.empty()) { 
        throw out_of_range("Stack<>::top(): empty stack"); 
    }
    // 返回最后一個(gè)元素的副本 
    return elems.back();      
} 
 
int main() 
{ 
    try { 
        Stack<int>         intStack;  // int 類(lèi)型的棧 
        Stack<string> stringStack;    // string 類(lèi)型的棧 
 
        // 操作 int 類(lèi)型的棧 
        intStack.push(7); 
        cout << intStack.top() <<endl; 
 
        // 操作 string 類(lèi)型的棧 
        stringStack.push("hello"); 
        cout << stringStack.top() << std::endl; 
        stringStack.pop(); 
        stringStack.pop(); 
    } 
    catch (exception const& ex) { 
        cerr << "Exception: " << ex.what() <<endl; 
        return -1;
    } 
}

// 輸出結(jié)果:
7
hello
Exception: Stack<>::pop(): empty stack

到了這里,關(guān)于C++中的泛型詳細(xì)講解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀(guān)點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Kotlin中的泛型理解與應(yīng)用

    泛型是一種在編程中用于增加代碼的靈活性和重用性的概念。它允許我們編寫(xiě)可以在多種類(lèi)型上工作的通用代碼,而不需要為每種類(lèi)型都編寫(xiě)不同的代碼。 在Kotlin中,泛型可以應(yīng)用于類(lèi)、函數(shù)和接口等。下面是一些關(guān)于泛型在Kotlin中的理解和示例。 1、泛型類(lèi) 泛型類(lèi)是指可以

    2024年02月07日
    瀏覽(24)
  • 詳解Java中的泛型(泛型的語(yǔ)法,擦除機(jī)制,泛型的上界)

    詳解Java中的泛型(泛型的語(yǔ)法,擦除機(jī)制,泛型的上界)

    目錄 一.什么是泛型 二.Java中為什么要使用泛型 三.泛型的語(yǔ)法 四.泛型類(lèi)的使用 五.泛型的編譯機(jī)制(擦除機(jī)制) 六.泛型的上界 泛型(Generics)是Java SE 5中引入的一個(gè)新特性,可以 使Java中的類(lèi)和方法具有更廣泛的類(lèi)型范圍 。通俗的說(shuō),它使得我們可以在定義類(lèi)和方法時(shí)指定

    2024年02月05日
    瀏覽(24)
  • Java 中的泛型(兩萬(wàn)字超全詳解)

    Java 中的泛型(兩萬(wàn)字超全詳解)

    博主將用 CSDN 記錄 Java 后端開(kāi)發(fā)學(xué)習(xí)之路上的經(jīng)驗(yàn),并將自己整理的編程經(jīng)驗(yàn)和知識(shí)分享出來(lái),希望能幫助到有需要的小伙伴。 博主也希望和一直在堅(jiān)持努力學(xué)習(xí)的小伙伴們共勉!唯有努力鉆研,多思考勤動(dòng)手,方能在編程道路上行至所向。 由于博主技術(shù)知識(shí)有限,博文中

    2024年02月04日
    瀏覽(16)
  • Java 中的泛型是什么,它有什么作用?(十五)

    Java中的泛型是一種類(lèi)型參數(shù)化機(jī)制,它使代碼更具可讀性、可重用性和穩(wěn)健性。在Java中,通過(guò)使用泛型,可以將類(lèi)型作為參數(shù)傳遞給類(lèi)或方法,并在編譯時(shí)執(zhí)行類(lèi)型檢查,從而避免許多運(yùn)行時(shí)錯(cuò)誤。 泛型的基礎(chǔ) Java泛型的基礎(chǔ)概念是類(lèi)型變量、類(lèi)型參數(shù)和類(lèi)型邊界。 類(lèi)型變

    2024年02月03日
    瀏覽(26)
  • 【Rust 基礎(chǔ)篇】Rust 中的泛型:結(jié)構(gòu)體和方法

    在 Rust 中,泛型是一種強(qiáng)大的特性,可以在結(jié)構(gòu)體和方法中使用通用的類(lèi)型參數(shù)。通過(guò)泛型,我們可以編寫(xiě)更加靈活和可復(fù)用的代碼。本篇博客將詳細(xì)介紹如何在 Rust 的結(jié)構(gòu)體和方法中使用泛型,包括泛型結(jié)構(gòu)體的定義、泛型方法的實(shí)現(xiàn)以及對(duì)泛型參數(shù)的約束。 在 Rust 中,我

    2024年02月16日
    瀏覽(24)
  • 第8章-第1節(jié)-Java中的泛型(參數(shù)化類(lèi)型)

    1、泛型在java中有很重要的地位,在面向?qū)ο缶幊碳案鞣N設(shè)計(jì)模式中有非常廣泛的應(yīng)用。什么是泛型?為什么要使用泛型? 2、概念:在類(lèi)聲明體中用到了類(lèi)型參數(shù)。 3、泛型類(lèi)只支持類(lèi)類(lèi)型,不支持基本數(shù)據(jù)類(lèi)型(如int),但可以用包裝類(lèi)(如Integer ) 泛型標(biāo)識(shí) 含義 T Type 類(lèi)

    2024年01月23日
    瀏覽(25)
  • ts 終于搞懂TS中的泛型啦! | typescript 入門(mén)指南 04

    ts 終于搞懂TS中的泛型啦! | typescript 入門(mén)指南 04

    大家好,我是王天~ 這篇文章是 ts入門(mén)指南系列中第四篇,主要講解ts中的泛型應(yīng)用,泛型在ts中是比較重要的概念,我花挺長(zhǎng)時(shí)間才搞明白的,希望能幫助到大家 ~ ** ts 入門(mén)指南系列 ** Ts和Js 誰(shuí)更適合前端開(kāi)發(fā)?| typescript 入門(mén)指南 01 詳解tsconfig.json 配置文件 | 02 ts入門(mén)指南

    2024年02月08日
    瀏覽(26)
  • C++之泛型算法

    大多數(shù)算法在頭文件algorithm中,在頭文件numeric中定義了一組數(shù)值泛型算法。理解算法最基本的方法就是了解他們是否讀取元素,改變?cè)?,或是重排元素順?使用STL算法經(jīng)常需要使用函數(shù)對(duì)象和函數(shù)適配器,所以需要#include 所有算法都被設(shè)計(jì)用來(lái)處理一個(gè)或多個(gè)iterator區(qū)間,

    2024年02月03日
    瀏覽(18)
  • c++泛型算法相關(guān)筆記

    c++泛型算法相關(guān)筆記

    泛型算法:可以支持多種類(lèi)型的算法 此處主要來(lái)討論怎么使用標(biāo)準(zhǔn)庫(kù)中定義的泛型算法 algorithm , numeric , ranges . 在引入泛型算法之前,還有一種是方法的形式,比如說(shuō) std::sort 和 std::list::sort ,前者是算法,后者是list類(lèi)中定義的函數(shù)(方法) 為什么引入泛型算法,而不用方法

    2024年01月19日
    瀏覽(14)
  • C++標(biāo)準(zhǔn)庫(kù) -- 泛型算法 (Primer C++ 第五版 · 閱讀筆記)

    C++標(biāo)準(zhǔn)庫(kù) -- 泛型算法 (Primer C++ 第五版 · 閱讀筆記)

    順序容器只定義了很少的操作:在多數(shù)情況下,我們可以添加和刪除元素訪(fǎng)問(wèn)首尾元素、確定容器是否為空以及獲得指向首元素或尾元素之后位置的迭代器。 我們可以想象用戶(hù)可能還希望做其他很多有用的操作:查找特定元素、替換或刪除一個(gè)特定值、重排元素順序等。 標(biāo)準(zhǔn)庫(kù)

    2023年04月21日
    瀏覽(27)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包