詳解C++模板編程中typename用法
typename的常規(guī)用法
typename在C++類模板或者函數(shù)模板中經(jīng)常使用的關(guān)鍵字,此時作用和class相同,只是定義模板參數(shù);在下面的例子中,該函數(shù)實現(xiàn)泛型交換數(shù)據(jù),即交換兩個數(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的第二個用法:修飾類型
限定名和非限定名
限定名(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;,然后使用時只用cout和endl,它們的前面不再有空間限定std::,所以此時的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; };
因為int是內(nèi)置類型,前三個定義的類型在聲明這個模板類時就已知,叫做非依賴名。然而對于接下來的三行定義,只有在模板實例化時才能知道它們的類型,因為它們都依賴于模板參數(shù)T。則T, vector<T>
, vector<T>::iterator
稱為依賴名。
類作用域
在類外部訪問類中的名稱時,可以使用類作用域操作符,調(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; };
下面來看一個例子:
template <class T> void function() { T::iterator *iter; ..... }
我們可能本意是想定義一個迭代器對象,例如我們?nèi)绻胿ector來實例化這個模板,那么iter
則應(yīng)該是一個迭代器指針,但是,如果我們用下面這個類來實例化這個模板
class cType { static int iterator; ... }; /* T::iterator *iter會被編譯器解釋為兩個數(shù)相乘。事實上,C++編譯器會采用第二種解釋方法,即使iterator的確是一個類型名。 為了避免這種矛盾,當(dāng)我們適用qualified dependent name的時候,需要用typename來指出這是一個類型名.即: typename T::iterator *iter; typename 指出下面緊跟著的名稱是一個類型 */ template <typename T> class Y { typename T::iterator *iter; typedef typename T::iterator iterator; //定義了Y::iterator類型名稱 ... };
T::iterator這種名稱,由于iterator具體是類型還是成員變量取決于T的類型實現(xiàn),所以當(dāng)我們知道T::iterator是個類型名稱時,如果我們要使用這個類型名,前面必須要加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++ 模擬實現(xiàn)list(迭代器)實現(xiàn)代碼
這篇文章主要介紹了C++ 模擬實現(xiàn)list(迭代器)實現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2017-05-05關(guān)于C++類的成員初始化列表的相關(guān)問題
下面小編就為大家?guī)硪黄P(guān)于C++類的成員初始化列表的相關(guān)問題。小編覺得挺2016-05-05C++實現(xiàn)LeetCode(136.單獨的數(shù)字)
這篇文章主要介紹了C++實現(xiàn)LeetCode(136.單獨的數(shù)字),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-07-07