問題:在下面的 template declarations(模板聲明)中 class 和 typename 有什麼不同?
template<class T> class Widget; // uses "class"
template<typename T> class Widget; // uses "typename"
答案:沒什麼不同。在聲明一個 template type parameter(模板型別參數)的時候,class 和 typename 意味著完全相同的東西。一些程式員更喜歡在所有的時間都用 class,因為它更容易輸入。其他人(包括我本人)更喜歡 typename,因為它暗示著這個參數不必要是一個 class type(類類型)。少數開發人員在任何類型都被允許的時候使用 typename,而把 class 保留給僅接受 user-defined types(使用者定義型別)的場合。但是從 C++ 的觀點看,class 和 typename 在聲明一個 template parameter(模板參數)時意味著完全相同的東西。
然而,C++ 並不總是把 class 和 typename 視為等同的東西。有時你必須使用 typename。為了理解這一點,我們不得不討論你會在一個 template(模板)中涉及到的兩種名字。
假設我們有一個函數的模板,它能取得一個 STL-compatible container(STL 相容容器)中持有的能賦值給 ints 的對象。進一步假設這個函數只是簡單地列印它的第二個元素的值。它是一個用糊塗的方法實現的糊塗的函數,而且就像我下面寫的,它甚至不能編譯,但是請將這些事先放在一邊——有一種方法能發現我的愚蠢:
template<typename C> // print 2nd element in
void print2nd(const C& container) // container;
{
// this is not valid C++!
if (container.size() >= 2) {
C::const_iterator iter(container.begin()); // get iterator to 1st element
++iter; // move iter to 2nd element
int value = *iter; // copy that element to an int
std::cout << value; // print the int
}
}
我突出了這個函數中的兩個 local variables(局部變數),iter 和 value。iter 的類型是 C::const_iterator,一個依賴於 template parameter(模板參數)C 的類型。一個 template(模板)中的依賴於一個 template parameter(模板參數)的名字被稱為 dependent names(依賴名字)。當一個 dependent names(依賴名字)嵌套在一個 class(類)的內部時,我稱它為 nested dependent name(嵌套依賴名字)。C::const_iterator 是一個 nested dependent name(嵌套依賴名字)。實際上,它是一個 nested dependent type name(嵌套依賴類型名),也就是說,一個涉及到一個 type(類型)的 nested dependent name(嵌套依賴名字)。