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

[C++歷練之路]C++模板還能這么玩,已經(jīng)走了好多彎路,后悔沒有早點學會到。

這篇具有很好參考價值的文章主要介紹了[C++歷練之路]C++模板還能這么玩,已經(jīng)走了好多彎路,后悔沒有早點學會到。。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

[C++歷練之路]C++模板還能這么玩,已經(jīng)走了好多彎路,后悔沒有早點學會到。,C++,c++,開發(fā)語言,人工智能,java,計算機網(wǎng)絡,linux

W...Y的主頁 ???

代碼倉庫分享???

?[C++歷練之路]C++模板還能這么玩,已經(jīng)走了好多彎路,后悔沒有早點學會到。,C++,c++,開發(fā)語言,人工智能,java,計算機網(wǎng)絡,linux


??前言:?

在C++的世界里,模板是一種強大而神奇的工具,宛如編程的瑰寶匣,蘊藏著無限的可能性。它們不僅能夠讓我們編寫通用的代碼,還能夠在編譯時實現(xiàn)類型安全的抽象。然而,模板的奧秘并非易見,它們像是編碼世界中的魔法咒語,需要睿智者的智慧和技巧才能真正駕馭。
在這段旅程中,我們將探索C++模板的奧秘,解鎖其妙用技巧的寶藏。我們將揭開模板編程的神秘面紗,探索如何借助模板實現(xiàn)泛型編程、容器類、算法以及更多令人驚嘆的功能。讓我們一同穿越這個編程的魔法門,發(fā)現(xiàn)模板編程的精妙所在,探索其中隱藏的無盡可能性。準備好了嗎?讓我們踏上這段模板編程之旅,探尋其中的精彩和奇跡。

目錄

什么是模板

?非類型模板參數(shù)

?模板的特化

概念

?函數(shù)模板特化

類模板特化

全特化

偏特化

模板分離編譯

什么是分離編譯

模板的分離編譯

解決方法

模板總結


什么是模板

在C++中,模板是一種泛型編程(Generic Programming)的工具,它允許程序員編寫通用的、與數(shù)據(jù)類型無關的代碼。使用模板,你可以編寫函數(shù)或類,使其能夠適用于多種數(shù)據(jù)類型而不需要重復編寫多份相似的代碼。

C++模板的兩種主要形式是函數(shù)模板和類模板:

函數(shù)模板: 函數(shù)模板允許你編寫一個通用的函數(shù),其中的某些類型或值可以是參數(shù)化的。例如,你可以編寫一個通用的排序函數(shù),可以對整數(shù)數(shù)組、浮點數(shù)數(shù)組或其他類型的數(shù)組進行排序,而不需要為每種類型都編寫一個獨立的排序函數(shù)。

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

這里,typename T 表示這是一個模板,并且 T 是一個占位符,代表了實際的數(shù)據(jù)類型。

類模板: 類模板允許你編寫通用的類,其中的某些成員可以是參數(shù)化的。例如,你可以編寫一個通用的棧類,可以存儲不同類型的元素。

template <typename T>
class Stack {
private:
    std::vector<T> elements;

public:
    void push(const T &element) {
        elements.push_back(element);
    }

    T pop() {
        if (!elements.empty()) {
            T top = elements.back();
            elements.pop_back();
            return top;
        } else {
            // Handle empty stack
            // ...
        }
    }
};

這里,template<typename T>表示這是一個類模板,T 是一個占位符,代表了實際的數(shù)據(jù)類型。

通過使用模板,可以實現(xiàn)更加靈活和可重用的代碼,因為它使得代碼可以獨立于具體的數(shù)據(jù)類型。在標準庫中,許多常見的數(shù)據(jù)結構和算法都是通過模板實現(xiàn)的。

?非類型模板參數(shù)

模板參數(shù)分類類型形參與非類型形參。
類型形參即:出現(xiàn)在模板參數(shù)列表中,跟在class或者typename之類的參數(shù)類型名稱。
非類型形參:就是用一個常量作為類(函數(shù))模板的一個參數(shù),在類(函數(shù))模板中可將該參數(shù)當成常量來使用。?

類型模板參數(shù)就是通過定義類型作為參數(shù)的,上面的代碼都是類型形參。

而非類型模板是什么呢?

當我們定義一個數(shù)組時使用#define可以進行宏定義,當我們創(chuàng)建一個數(shù)組時就可以數(shù)量為20的數(shù)組。?

#include <vector>
using namespace std;
#define n 20
 //類型模板參數(shù)
 //非類型模板參數(shù) -- 整形常量
template<class T>
class Array
{
private:
	T _a[n];
};
int main()
{
	Array<int> a1;
	Array<double> a2;
	return 0;
}

但是當我們想要進行創(chuàng)建一個空間個數(shù)為10的數(shù)組時就無法去創(chuàng)建,只能重新在定義一個模板進行。

非類型模板參數(shù)可以代替宏定義?。?!這時非類型模板就可以起到用處:

template<class T, size_t n = 20>
class Array
{
private:
	T _a[n];
};
int main()
{
	Array<int, 10> a1;
	Array<int> a;
	Array<double, 100> a2;
	return 0;
}

注意:
1. 浮點數(shù)、類對象以及字符串是不允許作為非類型模板參數(shù)的。
2. 非類型的模板參數(shù)必須在編譯期就能確認結果。

C++11中在STL中添加了新的容器,array容器。[C++歷練之路]C++模板還能這么玩,已經(jīng)走了好多彎路,后悔沒有早點學會到。,C++,c++,開發(fā)語言,人工智能,java,計算機網(wǎng)絡,linux

[C++歷練之路]C++模板還能這么玩,已經(jīng)走了好多彎路,后悔沒有早點學會到。,C++,c++,開發(fā)語言,人工智能,java,計算機網(wǎng)絡,linux

這個容器就是數(shù)組,使用了非類型模板參數(shù),所以在函數(shù)接口中就沒有rserve與rsize了。那這個容器好不好呢??

int arr[10];
array<int, 10> a1;
//這兩個是相同對標的

他們有什么區(qū)別呢?就是在越界檢測方式不同,數(shù)組的檢測方式是抽查寫,而array是全面檢測。但是這個東西不是很好,我們都可以使用vector了,為什么還要使用array呢?這里只是給大家做一個了解。

?模板的特化

概念

通常情況下,使用模板可以實現(xiàn)一些與類型無關的代碼,但對于一些特殊類型的可能會得到一些錯誤的結果,需要特殊處理,比如:實現(xiàn)了一個專門用來進行小于比較的函數(shù)模板

// 函數(shù)模板 -- 參數(shù)匹配
template<class T>
bool Less(T left, T right)
{
return left < right;
}
int main()
{
cout << Less(1, 2) << endl; // 可以比較,結果正確
Date d1(2022, 7, 7);
Date d2(2022, 7, 8);
cout << Less(d1, d2) << endl; // 可以比較,結果正確
Date* p1 = &d1;
Date* p2 = &d2;
cout << Less(p1, p2) << endl; // 可以比較,結果錯誤
return 0;
}

可以看到,Less絕對多數(shù)情況下都可以正常比較,但是在特殊場景下就得到錯誤的結果。上述示例中,p1指向的d1顯然小于p2指向的d2對象,但是Less內(nèi)部并沒有比較p1和p2指向的對象內(nèi)容,而比較的是p1和p2指針的地址,這就無法達到預期而錯誤。
此時,就需要對模板進行特化。即:在原模板類的基礎上,針對特殊類型所進行特殊化的實現(xiàn)方式。模板特化中分為函數(shù)模板特化與類模板特化。?

?函數(shù)模板特化

函數(shù)模板的特化步驟:
1. 必須要先有一個基礎的函數(shù)模板
2. 關鍵字template后面接一對空的尖括號<>
3. 函數(shù)名后跟一對尖括號,尖括號中指定需要特化的類型
4. 函數(shù)形參表:?必須要和模板函數(shù)的基礎參數(shù)類型完全相同,如果不同編譯器可能會報一些奇怪的錯誤。

// 函數(shù)模板 -- 參數(shù)匹配
template<class T>
bool Less(T left, T right)
{
return left < right;
}
// 對Less函數(shù)模板進行特化
template<>
bool Less<Date*>(Date* left, Date* right)
{
return *left < *right;
}
int main()
{
cout << Less(1, 2) << endl;
Date d1(2022, 7, 7);
Date d2(2022, 7, 8);
cout << Less(d1, d2) << endl;
Date* p1 = &d1;
Date* p2 = &d2;
cout << Less(p1, p2) << endl; // 調(diào)用特化之后的版本,而不走模板生成了
return 0;
}

?注意:一般情況下如果函數(shù)模板遇到不能處理或者處理有誤的類型,為了實現(xiàn)簡單通常都是將該函數(shù)直接給出。

bool Less(Date* left, Date* right)
{
    return *left < *right;
}

該種實現(xiàn)簡單明了,代碼的可讀性高,容易書寫,因為對于一些參數(shù)類型復雜的函數(shù)模板,特化時特別給出,因此函數(shù)模板不建議特化。

類模板特化

全特化

全特化即是將模板參數(shù)列表中所有的參數(shù)都確定化。

template<class T>
bool Less(T left, T right)
{
	return left < right;
}
template<>
bool Less<Date*>(Date* left, Date* right)
{
	return *left < *right;
}
int main()
{
	cout << Less(1, 2) << endl;   // 可以比較,結果正確

	Date d1(2022, 7, 7);
	Date d2(2022, 7, 8);
	cout << Less(d1, d2) << endl;  // 可以比較,結果正確

	Date* p1 = &d1;
	Date* p2 = &d2;
	cout << Less(p1, p2) << endl;  // 可以比較,結果錯誤

	int* p3 = new int(1);
	int* p4 = new int(2);
	cout << Less(p3, p4) << endl;  // 可以比較

	return 0;
}

全特化是對模板一種特殊處理,因為模板中有一部分內(nèi)容的比較結果與現(xiàn)實不符,我們必須特殊處理。所以必須有模板才能有特化類模板。

偏特化

偏特化:任何針對模版參數(shù)進一步進行條件限制設計的特化版本。比如對于以下模板類:

template<class T1, class T2>
class Data
{
public:
Data() {cout<<"Data<T1, T2>" <<endl;}
private:
T1 _d1;
T2 _d2;
};

偏特化有以下兩種表現(xiàn)方式:
部分特化
將模板參數(shù)類表中的一部分參數(shù)特化:

// 將第二個參數(shù)特化為int
template <class T1>
class Data<T1, int>
{
public:
Data() {cout<<"Data<T1, int>" <<endl;}
private:
T1 _d1;
int _d2;
};

參數(shù)更進一步的限制
偏特化并不僅僅是指特化部分參數(shù),而是針對模板參數(shù)更進一步的條件限制所設計出來的一個特化版本。

//兩個參數(shù)偏特化為指針類型
template <typename T1, typename T2>
class Data <T1*, T2*>
{
public:
Data() {cout<<"Data<T1*, T2*>" <<endl;}
private:
T1 _d1;
T2 _d2;
};
//兩個參數(shù)偏特化為引用類型
template <typename T1, typename T2>
class Data <T1&, T2&>
{
public:
Data(const T1& d1, const T2& d2)
: _d1(d1)
, _d2(d2)
{
cout<<"Data<T1&, T2&>" <<endl;
}
private:
const T1 & _d1;
const T2 & _d2;
};
void test2 ()
{
Data<double , int> d1; // 調(diào)用特化的int版本
Data<int , double> d2; // 調(diào)用基礎的模板
Data<int *, int*> d3; // 調(diào)用特化的指針版本
Data<int&, int&> d4(1, 2); // 調(diào)用特化的指針版本
}

模板分離編譯

什么是分離編譯

一個程序(項目)由若干個源文件共同實現(xiàn),而每個源文件單獨編譯生成目標文件,最后將所有目標文件鏈接起來形成單一的可執(zhí)行文件的過程稱為分離編譯模式。

模板的分離編譯

假如有以下場景,模板的聲明與定義分離開,在頭文件中進行聲明,源文件中完成定義:

// a.h
template<class T>
T Add(const T& left, const T& right);
// a.cpp
template<class T>
T Add(const T& left, const T& right)
{
return left + right;
}
// main.cpp
#include"a.h"
int main()
{
Add(1, 2);
Add(1.0, 2.0);
return 0;
}

[C++歷練之路]C++模板還能這么玩,已經(jīng)走了好多彎路,后悔沒有早點學會到。,C++,c++,開發(fā)語言,人工智能,java,計算機網(wǎng)絡,linux

?分析:[C++歷練之路]C++模板還能這么玩,已經(jīng)走了好多彎路,后悔沒有早點學會到。,C++,c++,開發(fā)語言,人工智能,java,計算機網(wǎng)絡,linux

[C++歷練之路]C++模板還能這么玩,已經(jīng)走了好多彎路,后悔沒有早點學會到。,C++,c++,開發(fā)語言,人工智能,java,計算機網(wǎng)絡,linux?func函數(shù)是有地址的,所以我們在鏈接時可以找到,但是模板卻沒有,所以編譯器在開辟函數(shù)棧幀時就不知道開多大空間,所以無法進行鏈接。

解決方法

1. 將聲明和定義放到一個文件 "xxx.hpp" 里面或者xxx.h其實也是可以的。推薦使用這種。

#include <vector>
using namespace std;

template<class T>
T Add(const T& left, const T& right);

void func();
template<class T>
T Add(const T& left, const T& right)
{
	return left + right;
}

 //聲明和定義放到一起,直接就可以實例化,編譯時就有地址,不需要鏈接

2. 模板定義的位置顯式實例化。這種方法不實用,不推薦使用。?

#define _CRT_SECURE_NO_WARNINGS 1
#include "Func.h"
template<class T>
T Add(const T& left, const T& right)
{
	return left + right;
}
void func()
{
	cout << "void func()" << endl;
}
template
double Add<double>(const double& left, const double& right);

template
int Add<int>(const int& left, const int& right);

?但是顯示實例化只能聲明一種類型,當我們需要另一種類型時就要重新實例化一個新類型。

模板總結

【優(yōu)點】
1. 模板復用了代碼,節(jié)省資源,更快的迭代開發(fā),C++的標準模板庫(STL)因此而產(chǎn)生
2. 增強了代碼的靈活性
【缺陷】
1. 模板會導致代碼膨脹問題,也會導致編譯時間變長
2. 出現(xiàn)模板編譯錯誤時,錯誤信息非常凌亂,不易定位錯誤

在這段模板之旅的終點,我們領略了C++模板的神奇之處,仿佛探索了編程的奇境。通過學習模板的一級運用技巧,我們擁有了一把打開泛型編程之門的鑰匙,能夠以更加通用和靈活的方式編寫代碼。文章來源地址http://www.zghlxwxcb.cn/news/detail-758731.html

到了這里,關于[C++歷練之路]C++模板還能這么玩,已經(jīng)走了好多彎路,后悔沒有早點學會到。的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

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

領支付寶紅包贊助服務器費用

相關文章

  • [C++歷練之路]優(yōu)先級隊列||反向迭代器的模擬實現(xiàn)

    [C++歷練之路]優(yōu)先級隊列||反向迭代器的模擬實現(xiàn)

    W...Y的主頁 ??? 代碼倉庫分享?? ??前言: 在C++的宇宙中,優(yōu)先隊列似乎是一座巨大的寶庫,藏匿著算法的珍寶。而就在這片代碼的天空下,我們不僅可以探索優(yōu)先隊列的神奇,還能夠揭開反向迭代器的神秘面紗。讓我們一同踏入這個編程的探險之旅,在這里,我們將用C

    2024年02月04日
    瀏覽(25)
  • 【C++歷練之路】list的重要接口||底層邏輯的三個封裝以及模擬實現(xiàn)

    【C++歷練之路】list的重要接口||底層邏輯的三個封裝以及模擬實現(xiàn)

    W...Y的主頁 ?? 代碼倉庫分享??? ??前言: 在C++的世界中,有一種數(shù)據(jù)結構,它不僅像一個神奇的瑰寶匣,還像一位能夠在數(shù)據(jù)的海洋中航行的智慧舵手。這就是C++中的list,一個引人入勝的工具,它以一種優(yōu)雅而強大的方式管理著數(shù)據(jù)的舞臺。想象一下,你有一個能夠輕松

    2024年02月04日
    瀏覽(16)
  • python 星號(*) 還能這么用

    哈嘍大家好,我是咸魚 今天跟大家介紹一下 python 當中星號( * )的一些用法 首先大家最常見的就是在 python 中 * 是乘法運算符,實現(xiàn)乘法 除此之外,還有一種常見的用法就是 * 號操作符在函數(shù)中的用法 單星號( * )在函數(shù)中用法 舉個例子,你有一個函數(shù),用來實現(xiàn)兩個數(shù)

    2024年02月09日
    瀏覽(21)
  • 深度盤點!ChatGPT 還能這么用?

    深度盤點!ChatGPT 還能這么用?

    開放隱私計算 ChatGPT能干什么? 你腦海中第一個想到的是不是“聊天”?但其實聊天只是我們和他交互的形式,他能干的事兒我們可以分為“基礎組件”和“組合套件”。先看“基礎組件”。 圖源網(wǎng)絡 一共有49項“基礎組件”!從最常規(guī)也是我們最熟知的問答,到科研黨常用

    2023年04月15日
    瀏覽(19)
  • selenium還能這么玩:連接手動打開的瀏覽器

    selenium還能這么玩:連接手動打開的瀏覽器

    粉絲交流群已開放,不定期分享面試題和視頻教程,點擊文末公眾號加群。 測試和爬蟲對selenium并不會陌生,現(xiàn)有的教程已經(jīng)非常多。但是因為 selenium 封裝的方法比較底層,所以靈活性非常高,我們可以基于這種靈活性來實現(xiàn)非常豐富的定制功能。 這篇文章介紹一個操作,

    2024年02月06日
    瀏覽(30)
  • 干貨分享:AI繪圖學習心得-Midjourney繪畫AI,讓你的AI繪畫之路少走彎路

    干貨分享:AI繪圖學習心得-Midjourney繪畫AI,讓你的AI繪畫之路少走彎路

    本篇沒有什么長篇大論,全部都是實用心得總結。接下來,我們將分享關于Midjourney繪畫AI的實用心得總結,包括構圖指令結構、常用指令、操作技巧、常用風格詞匯和構圖詞匯。 如果你想入門MidJourney可以查看這篇教程:Midjourney最全操作指南,從入門到精通 AI繪畫的核心就是

    2024年02月11日
    瀏覽(30)
  • 【C++航海王:追尋羅杰的編程之路】關于模板,你知道哪些?

    【C++航海王:追尋羅杰的編程之路】關于模板,你知道哪些?

    目錄 1 - 泛型編程 2 - 函數(shù)模板 2.1 - 函數(shù)模板概念 2.2 - 函數(shù)模板格式 2.3 - 函數(shù)模板的原理 2.4 - 函數(shù)模板的實例化 2.5 - 函數(shù)參數(shù)的匹配原則 3 - 類模板 3.1 - 類模板的定義格式 3.2 - 類模板的實例化 怎樣實現(xiàn)一個通用的交換函數(shù)? 使用函數(shù)重載雖然可以實現(xiàn),但是有幾個不好的

    2024年02月20日
    瀏覽(25)
  • 【C++航海王:追尋羅杰的編程之路】關于模板,你知道哪些?

    【C++航海王:追尋羅杰的編程之路】關于模板,你知道哪些?

    目錄 1 - 非類型模板參數(shù) 2 - 模板的特化 2.1 - 概念 2.2 - 函數(shù)模板的特化 2.3 - 類模板的特化 2.3.1 - 全特化 2.3.2 - 偏特化 2.3.3 - 類模板特化應用實例 3 - 模板分離編譯 3.1 - 什么是分離編譯 3.2 - 模板的分離編譯 3.3 - 解決方法 4 - 模板總結 模板參數(shù)分為類型形參與非類型形參。 類型

    2024年04月11日
    瀏覽(23)
  • SpringerLink施普林格旗下期刊latex模板下載方法——我已經(jīng)附上latex模版,免費下載,以Applied Intelligence期刊為例,一通百通?。。? decoding=

    SpringerLink施普林格旗下期刊latex模板下載方法——我已經(jīng)附上latex模版,免費下載,以Applied Intelligence期刊為例,一通百通?。?!

    https://link.springer.com/journal/10489/submission-guidelines?utm_medium=displayutm_source=letpubutm_content=text_linkutm_term=nullutm_campaign=MPSR_10489_AWA1_CN_CNPL_letpb_mp 百度云如下: 鏈接:https://pan.baidu.com/s/18p_tICkFx0H19vd3RdzGkg 提取碼:3pc4 CSDN資源如下: https://download.csdn.net/download/qlkaicx/88913130

    2024年04月26日
    瀏覽(91)
  • 面試官:只知道v-model是:modelValue和@onUpdate語法糖,那你可以走了

    面試官:只知道v-model是:modelValue和@onUpdate語法糖,那你可以走了

    我們每天都在用 v-model ,并且大家都知道在vue3中 v-model 是 :modelValue 和 @update:modelValue 的語法糖。那你知道 v-model 指令是如何變成組件上的 modelValue 屬性和 @update:modelValue 事件呢?將 v-model 指令轉(zhuǎn)換為 modelValue 屬性和 @update:modelValue 事件這一過程是在編譯時還是運行時進行的呢

    2024年03月26日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

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

二維碼1

領取紅包

二維碼2

領紅包