溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++非模板類型參數怎么用

發(fā)布時間:2022-01-17 09:01:36 來源:億速云 閱讀:158 作者:iii 欄目:開發(fā)技術

本篇內容介紹了“C++非模板類型參數怎么用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

    一、非模板類型參數

    分類:

    模板參數分類類型形參與非類型形參

    概念:

    1.類型形參:

    出現在模板參數列表中,跟在class或者typename之類的參數類型名稱

    2.非類型形參:

    用一個常量作為類(函數)模板的一個參數,在類(函數)模板中可將該參數當成常量來使用

    示例:

    namespace cole
    {
    	// 定義一個模板類型的靜態(tài)數組
    	template<class T, size_t N = 10>
    	class array
    	{
    	public:
    		T& operator[](size_t index) 
    		{ 
    			return _array[index]; 
    		}
    
    		const T& operator[](size_t index)const 
    		{ 
    			return _array[index]; 
    		}
    
    		size_t size()const 
    		{ 
    			return _size; 
    		}
    
    		bool empty()const 
    		{ 
    			return 0 == _size; 
    		}
    	private:
    		T _array[N];
    		size_t _size;
    	};
    }

    注意:

    1.浮點數、類對象以及字符串是不允許作為非類型模板參數的

    2.非類型的模板參數必須在編譯期就能確認結果

    二、模板特化

    概念:

    使用模板可以實現一些與類型無關的代碼,但對于一些特殊類型的可能會得到一些錯誤的結果

    示例:

    template<class T>
    bool IsEqual(const T& left, const T& right)
    {
    	return left == right;
    }
    // 函數模板的特化 (針對某些類型的特殊化處理)
    //bool IsEqual(const char* const & left,const char* const & right)
    bool IsEqual(const char* left, const char* right)
    {
    	return strcmp(left, right) == 0;
    }
    int main()
    {
    	cout << IsEqual(1, 2) << endl;
    	char p1[] = "hello";
    	char p2[] = "hello";
    	cout << IsEqual(p1, p2) << endl;;
    	return 0;
    }

    特殊化結果:

    C++非模板類型參數怎么用

     不做特殊化結果:

     C++非模板類型參數怎么用

    注:此時對于字符串比較就需要對模板進行特化(在原模板類的基礎上,針對特殊類型所進行特殊化的實現方式)

    特化分類:

    函數模板特化類模板特化

    1、函數模板特化

    函數模板的特化步驟:

    • 必須要先有一個基礎的函數模板

    • 關鍵字template后面接一對空的尖括號<>

    • 函數名后跟一對尖括號,尖括號中指定需要特化的類型

    • 函數形參表: 必須要和模板函數的基礎參數類型完全相同,如果不同編譯器可能會報一些奇怪的錯誤

    示例:

    template<class T>
    bool IsEqual(const T left, const T right)
    {
    	return left == right;
    }
    template<>
    bool IsEqual<char*>(char* left,char* right)
    {
    	if (strcmp(left, right) == 0)
    		return true;
    	return false;
    }

    結果:

     C++非模板類型參數怎么用

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

    示例:

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

    2、類模板特化

    1)全特化

    概念:

    全特化即是將模板參數列表中所有的參數都確定化

    示例:

    template<class T1, class T2>
    class Data
    {
    public:
    	Data() { cout << "Data<T1, T2>" << endl; }
    private:
    	T1 _d1;
    	T2 _d2;
    };
    template<>
    class Data<int, char>
    {
    public:
    	Data() { cout << "Data<int, char>" << endl; }
    private:
    	int _d1;
    	char _d2;
    };
    void TestVector()
    {
    	Data<int, int> d1;
    	Data<int, char> d2;
    }
    2)偏特化

    概念:

    任何針對模版參數進一步進行條件限制設計的特化版本

    偏特化有以下兩種表現方式:

    1.部分特化

    將模板參數類表中的一部分參數特化

    示例:

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

    2.參數更進一步的限制

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

    示例:

    //兩個參數偏特化為指針類型template <typename T1, typename T2>class Data <T1*, T2*>{public:Data() { cout << "Data<T1*, T2*>" << endl; }private:T1 _d1;T2 _d2;};//兩個參數偏特化為引用類型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; // 調用特化的int版本Data<int, double> d2; // 調用基礎的模板Data<int*, int*> d3; // 調用特化的指針版本Data<int&, int&> d4(1, 2); // 調用特化的指針版本}//兩個參數偏特化為指針類型
    template <typename T1, typename T2>
    class Data <T1*, T2*>
    {
    public:
    	Data() { cout << "Data<T1*, T2*>" << endl; }
    private:
    	T1 _d1;
    	T2 _d2;
    };
    //兩個參數偏特化為引用類型
    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; // 調用特化的int版本
    	Data<int, double> d2; // 調用基礎的模板
    	Data<int*, int*> d3; // 調用特化的指針版本
    	Data<int&, int&> d4(1, 2); // 調用特化的指針版本
    }

    三、模板分離編譯

    分離編譯概念:

    一個程序(項目)由若干個源文件共同實現,而每個源文件單獨編譯生成目標文件,最后將所有目標文件鏈接起來形成單一的可執(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++非模板類型參數怎么用

    解決方法

    1.將聲明和定義放到一個文件 “xxx.hpp” (h文件和cpp文件結合)里面或者xxx.h其實也是可以的(推薦)

    2.模板定義的位置顯式實例化(不實用)

    四、模板總結

    優(yōu)點:

    • 模板復用了代碼,節(jié)省資源,更快的迭代開發(fā),C++的標準模板庫(STL)因此而產生

    • 增強了代碼的靈活性

    缺陷:

    • 模板會導致代碼膨脹問題,也會導致編譯時間變長(為了盡量減少此類問題,編譯器會按需實例化)

    • 出現模板編譯錯誤時,錯誤信息非常凌亂,不易定位錯誤

    • 不支持分離編譯

    “C++非模板類型參數怎么用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    c++
    AI