Typename和Class在宣告模板時的區別

2022-08-11 16:51:17 字數 1450 閱讀 7037

(1)templateclass widget;

(2)templateclass widget。

然而c++並不總是把class和typename視為等價。有時一定得使用typename。

這種時機就是:任何時候當想要在template中指涉乙個巢狀從屬型別名稱,就必須在緊鄰它的前乙個位置放上關鍵字typename,只有如下乙個例外:不得在base class list(基類列)或member initializationlist(成員初值列)內以它作為base class修飾符。其中:template內出現的名稱如果相依於某個template引數,稱之為從屬名稱。如果從屬名稱在class內呈巢狀狀,我們稱它為巢狀從屬名稱。c::const_iterator(看下面例子)就是這樣的乙個名稱。實際上它還是個巢狀從屬型別名稱,也就是個巢狀從屬名稱並且指涉某型別。看下面例子:

template

void print2nd(const c& container)

}巢狀從屬名稱有可能引起解析困難。如下面的例子(將上面的改一下):

template

void print2nd(const c& container)

按照正常的理解我們應該是宣告了乙個x的區域性變數,但是前提是我們知道c::const_iterator是個型別,但是萬一不是呢,比如c是個類並且它有乙個const_iterator的靜態成員變數呢而且x又是乙個全域性變數,那麼上面的就是乙個相乘的動作,即c::const_iterator乘以x。引起歧義。

在我們知道c是什麼之前,沒有任何辦法可以知道c::const_iterator是否是乙個型別。而當編譯器開始解析template print2nd時,尚未知c是什麼東西。c++有個規則可以解析此一歧義狀態:如果解析器在template中遭遇乙個巢狀從屬名稱,它便假設這名稱不是乙個型別,除非你告訴它是。所以預設情況下巢狀從屬名稱不是型別。此規則有個例外,稍後會談到。我們告訴它是只需在c::const_iterator前加上關鍵字typename即可。

注意typename只被用來驗明巢狀從屬型別名稱;其他名稱不該有它存在。如下面的例子:

template

void f(const c& container,typename c::iterator iter)。引數中第乙個不是巢狀從屬型別名稱,所以不需要關鍵字typename,而第二個需要。

「typename必須作為巢狀從屬型別名稱的字首詞」這一規則的例外是,typename不可以出現在base classes list內的巢狀從屬型別名稱之前,也不可在member initalization list(成員初始列)中作為base class修飾符。例如:

template

class derived:public base::nested //base list中不允許"typename"

}最後宣告一點:以上講的在vc++ 6.0下不適用,也就是說在vc下不用typename修飾巢狀從屬型別,編譯器也不會抱怨,但是在gcc核心下就會發生抱怨。

C 中typename和class的區別

在c template中很多地方都用到了typename與class這兩個關鍵字,而且好像可以替換,是不是這兩個關鍵字完全一樣呢?相信學習c 的人對class這個關鍵字都非常明白,class用於定義類,在模板引入c 後,最初定義模板的方法為 template.在這裡class關鍵字表明t是乙個型別,...

定義模板時typename和class的區別

在c template中很多地方都用到了typename與class這兩個關鍵字,而且好像可以替換,是不是這兩個關鍵字完全一樣呢?相信學習c 的人對class這個關鍵字都非常明白,class用於定義類,在模板引入c 後,最初定義模板的方法為 template.在這裡class關鍵字表明t是乙個型別,...

C 中typename和class的區別

在c template中很多地方都用到了typename與class這兩個關鍵字,而且好像可以替換,是不是這兩個關鍵字完全一樣呢?相信學習c 的人對class這個關鍵字都非常明白,class用於定義類,在模板引入c 後,最初定義模板的方法為 template.在這裡class關鍵字表明t是乙個型別,...