看了很多遍,還是記錄一下
template class widget;
// uses "class"
template class widget;
// uses "typename"
兩面的兩句等價
template
void
print2nd
(const c& container)
此時的編譯器會糾結:const_iterator是乙個什麼東西?const_iterator是模板引數c內的乙個static變數?x是乙個全域性變數?
再或者:const_iterator是模板引數c內部的乙個typedef。假設模板引數c最後用class_c來例項化,class_c類似這樣:
class class_c;
那上面的例子中的語句①就是宣告乙個指向int型別的指標x,語句①轉化過來就是這樣:
int *x;
程式設計師是不能讓編譯器糾結的,編譯器糾結的後果是:報錯。程式設計師嘛,就debug吧。
所以此時我們應該告訴編譯器const_iterator是模板引數c裡面的乙個型別。即在c的前面加上typename就可以了,像這樣:
template
void
print2nd
(const c& container)
a、模板內出現的名稱如果依賴於某個模板引數,稱之為從屬名稱(dependent name)。如果從屬名稱在class內呈巢狀狀,我們稱為巢狀從屬名稱(nested dependent name)。距離如下:
template
void
print
(const c & container)
b、再來看乙個例子:
template
// typename allowed (as is "class")
voidf(
const c& container,
// typename not allowed
typename c:
:iterator iter)
;// typename required
上述的c並不是巢狀從屬型別名稱(它並非巢狀與任何「取決於模板引數」的東西內),所以宣告container時並不需要以typename為前導。
但c::iterator是個巢狀從屬型別名稱,所以必須以typename為前導。
c、說人話
使用某個模板類裡面typedef的型別時,如果這個型別與模板引數c相關,就需要使用typename。
即這樣的形式:
y(c)::iterator it;
這樣的語句前面就需要前置typename;
參考:[1]
[2]
C 迴圈巢狀 常見的巢狀
迴圈的巢狀就是,乙個迴圈體內又包含了另乙個完整的迴圈結構 內嵌的迴圈中還可以巢狀迴圈,這就是多層迴圈。在c 中,while迴圈 do while迴圈 for迴圈都可以互相巢狀,例如以下幾種 while語句巢狀while語句 while do while語句巢狀do while語句 do while ...
C 特殊的「別名」引用
1 在c 中新增加了引用的概念 2 引用可以看作乙個已定義變數的別名 3 引用的語法 type name var 4 引用做函式引數那?引用作為函式引數宣告時不進行初始化 例項 include include intmain void 屬於c 編譯器對c的擴充套件。例項 問題 c中可以編譯通過嗎?i...
C 擴充套件列舉的別名
c 擴充套件列舉的別名 用途 提高 的可讀性.列印到日誌系統,方便於除錯.首先編寫乙個attribute attributeusage attributetargets.enum attributetargets.field,allowmultiple false,inherited false p...