詳解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
則應該是一個迭代器指針,但是,如果我們用下面這個類來實例化這個模板
class cType
{
static int iterator;
...
};
/*
T::iterator *iter會被編譯器解釋為兩個數(shù)相乘。事實上,C++編譯器會采用第二種解釋方法,即使iterator的確是一個類型名。
為了避免這種矛盾,當我們適用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),所以當我們知道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語言中調(diào)用shell命令的實現(xiàn)方法
本篇文章是對如何在C語言中調(diào)用shell命令的方法進行了詳細的分析介紹,需要的朋友參考下2013-05-05

