詳解C++模板編程中typename用法
typename的常規(guī)用法
typename在C++類模板或者函數(shù)模板中經(jīng)常使用的關(guān)鍵字,此時(shí)作用和class相同,只是定義模板參數(shù);在下面的例子中,該函數(shù)實(shí)現(xiàn)泛型交換數(shù)據(jù),即交換兩個(gè)數(shù)據(jù)的內(nèi)容,數(shù)據(jù)的類型由_Tp決定。
template <typename _Tp>
inline void swap(_Tp& __a, _Tp& __b)
{
_Tp __tmp = __a;
__a = __b;
__b = __tmp;
}
typename的第二個(gè)用法:修飾類型
限定名和非限定名
限定名(qualified name),是限定了命名空間的名稱。看下面這段代碼,cout和endl是在命名空間std定義的,必須加上std::,使其為std::cout和std::endl,因此稱其為限定名。
#include <iostream>
int main()
{
std::cout << "Hello world!" << std::endl;
}
若在主函數(shù)前面使用using namespace std;或者在主函數(shù)內(nèi)使用using std::cout;,然后使用時(shí)只用cout和endl,它們的前面不再有空間限定std::,所以此時(shí)的cout和endl叫做非限定名(unqualified name)。
#include <iostream>
using namespace std;
int main()
{
using std::cout;
using std::endl;
cout << "Hello world!" << endl;
}
依賴名和非依賴名
依賴名(dependent name)是指依賴于模板參數(shù)的名稱,而非依賴名(non-dependent name)則相反,指不依賴于模板參數(shù)的名稱??聪旅孢@段代碼:
template <class T>
class MyClass
{
int i;
vector<int> vi;
vector<int>::iterator vitr;
T t;
vector<T> vt;
vector<T>::iterator viter;
};
因?yàn)閕nt是內(nèi)置類型,前三個(gè)定義的類型在聲明這個(gè)模板類時(shí)就已知,叫做非依賴名。然而對于接下來的三行定義,只有在模板實(shí)例化時(shí)才能知道它們的類型,因?yàn)樗鼈兌家蕾囉谀0鍏?shù)T。則T, vector<T>, vector<T>::iterator稱為依賴名。
類作用域
在類外部訪問類中的名稱時(shí),可以使用類作用域操作符,調(diào)用通常存在三種:靜態(tài)數(shù)據(jù)成員、靜態(tài)成員函數(shù)和嵌套類型:Metadata::value,Metadata::function,Metadata::ValueType;
class Metadata {
static int value;
static int function();
typedef std::string ValueType;
};
下面來看一個(gè)例子:
template <class T>
void function()
{
T::iterator *iter;
.....
}
我們可能本意是想定義一個(gè)迭代器對象,例如我們?nèi)绻胿ector來實(shí)例化這個(gè)模板,那么iter
則應(yīng)該是一個(gè)迭代器指針,但是,如果我們用下面這個(gè)類來實(shí)例化這個(gè)模板
class cType
{
static int iterator;
...
};
/*
T::iterator *iter會(huì)被編譯器解釋為兩個(gè)數(shù)相乘。事實(shí)上,C++編譯器會(huì)采用第二種解釋方法,即使iterator的確是一個(gè)類型名。
為了避免這種矛盾,當(dāng)我們適用qualified dependent name的時(shí)候,需要用typename來指出這是一個(gè)類型名.即: typename T::iterator *iter;
typename 指出下面緊跟著的名稱是一個(gè)類型
*/
template <typename T> class Y
{
typename T::iterator *iter;
typedef typename T::iterator iterator; //定義了Y::iterator類型名稱
...
};
T::iterator這種名稱,由于iterator具體是類型還是成員變量取決于T的類型實(shí)現(xiàn),所以當(dāng)我們知道T::iterator是個(gè)類型名稱時(shí),如果我們要使用這個(gè)類型名,前面必須要加typename.
typename使用規(guī)則
typename在下面情況下禁止使用:
- 模板定義之外,即typename只能用于模板的定義中
- 非限定類型,比如int,
vector<int>之類 - 基類列表中,比如
template <class T> class C1 : T::InterType不能在T::InterType前面加typename - 構(gòu)造函數(shù)的初始化列表中,如果類型是依賴于模板參數(shù)的限定名,那么在它之前必須加typename(除非是基類列表,或者在類的初始化成員列表中)。
到此這篇關(guān)于詳解C++模板編程中typename用法的文章就介紹到這了,更多相關(guān)c++模板typename內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++中內(nèi)存池的簡單原理及實(shí)現(xiàn)詳解
內(nèi)存池的思想是,在真正使用內(nèi)存之前,預(yù)先申請分配一定數(shù)量、大小預(yù)設(shè)的內(nèi)存塊留作備用。本文主要來和大家聊聊內(nèi)存池的簡單原理及實(shí)現(xiàn),希望對大家有所幫助2023-03-03
C++ 模擬實(shí)現(xiàn)list(迭代器)實(shí)現(xiàn)代碼
這篇文章主要介紹了C++ 模擬實(shí)現(xiàn)list(迭代器)實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2017-05-05
C語言實(shí)現(xiàn)電子英漢詞典系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)電子英漢詞典系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
關(guān)于C++類的成員初始化列表的相關(guān)問題
下面小編就為大家?guī)硪黄P(guān)于C++類的成員初始化列表的相關(guān)問題。小編覺得挺2016-05-05
C++設(shè)計(jì)模式之裝飾模式(Decorator)
這篇文章主要為大家詳細(xì)介紹了C++設(shè)計(jì)模式之裝飾模式Decorator的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03
Qt實(shí)戰(zhàn)之實(shí)現(xiàn)圖片瀏覽器
這篇文章主要為大家詳細(xì)介紹了如何利用Qt實(shí)現(xiàn)簡易的圖片瀏覽器,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴可以了解一下2023-03-03
C++實(shí)現(xiàn)LeetCode(136.單獨(dú)的數(shù)字)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(136.單獨(dú)的數(shù)字),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07

