欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++數(shù)據(jù)結(jié)構(gòu)模板進(jìn)階的多方面分析

 更新時間:2022年02月28日 17:05:15   作者:呆呆獸學(xué)編程  
今天我要給大家介紹C++中的模板更深的一些知識。有關(guān)于非類型的模板參數(shù)和模板特化的一些知識,感興趣的朋友快來看看吧

??博客代碼已上傳至gitee:https://gitee.com/byte-binxin/cpp-class-code

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

模板參數(shù)分類類型形參與非類型形參。

  • 類型模板形參:出現(xiàn)在模板參數(shù)列表中,跟在class或者typename后面的參數(shù)類型名稱。(這個我們之前有講過)
  • 非類型模板形參:用一個常量作為模板的一個參數(shù),必須是整形家族中的類型參數(shù),否則不行。他在模板中可以當(dāng)常量使用。

實(shí)例:

// 類型模板參數(shù)
namespace wxj
{
	// 非類型模板參數(shù) N 是一個常量參數(shù),只能是整形家族的:int short char long  long long    自定義類型和其他類型都不能作費(fèi)類型模板參數(shù)
	// 必須在編譯期就能確認(rèn)結(jié)果
	template<class T, size_t N = 10>
	class Array
	{
	public:
		Array()
			:_size(N)
		{}
		T& operator[](size_t i)
		{
			return _arr[i];
		}
		const T& operator[](size_t i) const
		{
			return _arr[i];
		}
		size_t size()
		{
			return _size;
		}
		bool empty()
		{
			return _size == 0;
		}
	private:
		T _arr[N];
		size_t _size;
	};

	void TestArray()
	{
		Array<int, 5> arr;
		for (size_t i = 0; i < arr.size(); ++i)
		{
			arr[i] = i;
		}
		for (size_t i = 0; i < arr.size(); ++i)
		{
			cout << arr[i] << " ";
		}
		cout << endl;
	}
}

int main()
{
	wxj::TestArray();
	return 0;
}

代碼運(yùn)行結(jié)果如下:

看上面,我們定義了一個數(shù)組類,空間大小由N決定,類型是Array<T, size_t>

注意:

  • 非類型形參必須是整形家族中的類型,浮點(diǎn)數(shù)和類對象都不行。
  • 非類型的模板形參必須在編譯期間就能確認(rèn)結(jié)果。

??模板的特化

模板特化:在原模板類的基礎(chǔ)上,針對特殊類型所進(jìn)行的特殊化的實(shí)現(xiàn)。分為函數(shù)模板特化 和類模板特化。

??函數(shù)模板的特化

特化的步驟

  • 必須先有一個基礎(chǔ)的函數(shù)模板
  • 關(guān)鍵字template后面接一對空的尖括號<>
  • 函數(shù)名后跟一對尖括號<>,里面指定需要的特化的類型
  • 函數(shù)形參列表:必須和函數(shù)模板的基礎(chǔ)參數(shù)類型完全一致

實(shí)例

// 模板的特化    模板的特殊化
template<class T>
bool IsEqual(T& left, T& right)
{
	return left == right;
}

 // 特化  針對某些類型進(jìn)行特殊化處理
template<>
bool IsEqual<const char* const>(const char* const& left, const char* const& right)
{
	return strcmp(left, right) == 0;
}

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

bool IsEqual(char* left, char* right)
{
	return strcmp(left, right) == 0;
}

??類模板的特化

類模板的特化分為全特化和偏特化。

全特化: 對類模板參數(shù)列表的類型全部都確定(明確指定)

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

// 全特化
template<>
class Date<int, double>
{
public:
	Date()
	{
		cout << "Date<int, double>" << endl;
	}
private:
	int _d1;
	double _d2;
};

偏特化: 堆類模板的參數(shù)列表中部分參數(shù)進(jìn)行確定化分為部分特化和參數(shù)進(jìn)一步限制

部分特化

// 部分
template<class T2>
class Date<int, T2>
{
public:
	Date()
	{
		cout << "Date<int, T2>" << endl;
	}
private:
	int _d1;
	T2 _d2;
};

參數(shù)進(jìn)一步限制 如下有T*和T&,是模板的類型轉(zhuǎn)為指針類型和引用類型

// 參數(shù)進(jìn)一步限制  堆模板參數(shù)更進(jìn)一步的條件限制
template <class T1, class T2>
class Date<T1*, T2&>
{
public:
	Date(int& a)
		:_d2(a)
	{
		cout << "Date<T1*, T2&>" << endl;
	}
private:
	T1* _d1;
	T2& _d2;
};

實(shí)例 我們試著實(shí)例化幾個對象,看他們用的是哪個模板

int main()
{
	Date<int, int> d1;
	Date<int, double> d2;
	Date<int, float> d3;
	int a = 10;
	Date<int*, int&> d4(a);
	return 0;
}

代碼運(yùn)行結(jié)果:

??模板的分離編譯

分離編譯: 我們對這個應(yīng)該是不陌生的,就是把函數(shù)的聲明放在一個叫**.h的文件中,實(shí)現(xiàn)都放在一個叫.cpp**的文件中,這樣方便我們管理。

下面我們試著對模板進(jìn)行分離編譯:

// a.h
#pragma once


// 普通函數(shù)
void Swap(int& a, int& b);
// 函數(shù)模板
template<class T>
T Add(const T& a, const T& b);

// a.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include "a.h"

// 普通函數(shù)
void Swap(int& a, int& b)
{
	int tmp = a;
	a = b;
	b = tmp;
}
// 函數(shù)模板
template<class T>
T Add(const T& a, const T& b)
{
	return a + b;
}

// test.cpp
#include "a.h"

int main()
{
	int a = 3;
	int b = 4;

	Swap(a, b);
	cout << "a = " << a << " b = " << b << endl;
	cout << Add(a, b) << endl;
	
	return 0;
}

代碼運(yùn)行結(jié)果如下

代碼運(yùn)行時發(fā)生了報錯,說Add這個函數(shù)是沒有見過的。得出結(jié)論:函數(shù)模板不能分離編譯,普通函數(shù)可以。

為什么會這樣呢?

C++程序運(yùn)行一般經(jīng)過幾個階段:預(yù)處理——>編譯——>匯編——>鏈接(更詳細(xì)的內(nèi)容可以參考往期博客——程序的編譯

  • 模板在.cpp中定義了,由于不知道T的類型,所以沒有對模板進(jìn)行實(shí)例化。
  • a.h 和 a.cpp 走的是兩條不同的路,兩條路都沒有對模板進(jìn)行實(shí)例化(因?yàn)椴恢繲的類型)。
  • 因?yàn)闆]有對模板進(jìn)行實(shí)例化,所以沒有函數(shù)參數(shù),也就沒有函數(shù)地址,所以在鏈接時,test.cpp中的調(diào)用Add函數(shù)時,沒有函數(shù)地址,call調(diào)用不到Add函數(shù),所以報錯。

解決方法:

  • 暴力:不分離編譯,統(tǒng)一放在一個.h或.hpp的文件中
  • 模板定義位置顯示實(shí)例化(不推薦,這樣就失去了泛型的特點(diǎn))

??總結(jié)

模板進(jìn)階也就是這些內(nèi)容了,喜歡的話,歡迎收藏支持~

到此這篇關(guān)于C++數(shù)據(jù)結(jié)構(gòu)模板進(jìn)階的多方面分析的文章就介紹到這了,更多相關(guān)C++ 模板進(jìn)階內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++示例講解string容器

    C++示例講解string容器

    c++相比c的一個好處就是實(shí)現(xiàn)了很多的容器和泛型算法,使得程序員的工作得到了很大的簡化,本文重點(diǎn)給大家介紹C++string容器基本概念講解,需要的朋友參考下吧
    2022-07-07
  • C語言三子棋小游戲的實(shí)現(xiàn)

    C語言三子棋小游戲的實(shí)現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了C語言三子棋小游戲的實(shí)現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • C++ 詳細(xì)講解對象的構(gòu)造順序

    C++ 詳細(xì)講解對象的構(gòu)造順序

    對象的構(gòu)造往往和構(gòu)造函數(shù)會牽扯在一起,構(gòu)造函數(shù)的函數(shù)可能會由非常復(fù)雜的邏輯所組成,不同類的構(gòu)造函數(shù)的程序邏輯很可能是相互依賴的,當(dāng)這種相互依賴一旦成立,那么對象的構(gòu)造順序很可能導(dǎo)致難以調(diào)試的Bug出現(xiàn)
    2022-04-04
  • C++?STL?中的數(shù)值算法示例講解

    C++?STL?中的數(shù)值算法示例講解

    本片文章講解了C++STL?中的數(shù)值算法,包含iota、accumulate、adjacent_difference、inner_product、partial_sum這些方法的使用,感興趣的朋友來看看吧<BR>
    2022-04-04
  • C語言實(shí)現(xiàn)字符串匹配KMP算法

    C語言實(shí)現(xiàn)字符串匹配KMP算法

    相信很多人(包括自己)初識KMP算法的時候始終是丈二和尚摸不著頭腦,要么完全不知所云,要么看不懂書上的解釋,要么自己覺得好像心里了解KMP算法的意思,卻說不出個究竟,所謂知其然不知其所以然是也。
    2014-08-08
  • c++ chrono 獲取當(dāng)前時間的實(shí)現(xiàn)代碼

    c++ chrono 獲取當(dāng)前時間的實(shí)現(xiàn)代碼

    這篇文章主要介紹了c++ chrono 獲取當(dāng)前時間的實(shí)現(xiàn)代碼,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • 使用VS2019編譯CEF2623項(xiàng)目的libcef_dll_wrapper.lib的方法

    使用VS2019編譯CEF2623項(xiàng)目的libcef_dll_wrapper.lib的方法

    這篇文章主要介紹了使用VS2019編譯CEF2623項(xiàng)目的libcef_dll_wrapper.lib的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • C語言程序的編譯與預(yù)處理基礎(chǔ)定義講解

    C語言程序的編譯與預(yù)處理基礎(chǔ)定義講解

    在ANSI C的任意一種實(shí)現(xiàn)中,存在2中不同的環(huán)境。第一種是翻譯環(huán)境,負(fù)責(zé)將源代碼轉(zhuǎn)換成可執(zhí)行的機(jī)器指令;第二種是執(zhí)行環(huán)境,用于實(shí)際執(zhí)行代碼。一個程序從源代碼到可執(zhí)行程序一共會經(jīng)歷四個過程,分別是預(yù)處理、編譯、匯編、鏈接,本篇讓我們來了解編譯與預(yù)處理
    2022-04-04
  • C 二分查找 遞歸與非遞歸的實(shí)現(xiàn)代碼

    C 二分查找 遞歸與非遞歸的實(shí)現(xiàn)代碼

    C 二分查找 遞歸與非遞歸的實(shí)現(xiàn)代碼,需要的朋友可以參考一下
    2013-03-03
  • MFC對話框?qū)崿F(xiàn)梯形分頁

    MFC對話框?qū)崿F(xiàn)梯形分頁

    這篇文章主要為大家詳細(xì)介紹了MFC對話框?qū)崿F(xiàn)梯形分頁,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06

最新評論