青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

twzheng's cppblog

『站在風口浪尖緊握住鼠標旋轉!』 http://www.cnblogs.com/twzheng

  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
  136 隨筆 :: 78 文章 :: 353 評論 :: 0 Trackbacks

[轉] typename 的兩個含義
【摘自】armman的專欄

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(嵌套依賴名字)。

  print2nd 中的另一個 local variable(局部變量)value 具有 int 類型。int 是一個不依賴于任何 template parameter(模板參數)的名字。這樣的名字以 non-dependent names(非依賴名字)聞名。

  nested dependent name(嵌套依賴名字)會導致解析困難。例如,假設我們更加愚蠢地以這種方法開始 print2nd:
template<typename C>
void print2nd(const C& container)
{
 C::const_iterator * x;
 ...
}
  這看上去好像是我們將 x 聲明為一個指向 C::const_iterator 的 local variable(局部變量)。但是它看上去如此僅僅是因為我們知道 C::const_iterator 是一個 type(類型)。但是如果 C::const_iterator 不是一個 type(類型)呢?如果 C 有一個 static data member(靜態數據成員)碰巧就叫做 const_iterator 呢?再如果 x 碰巧是一個 global variable(全局變量)的名字呢?在這種情況下,上面的代碼就不是聲明一個 local variable(局部變量),而是成為 C::const_iterator 乘以 x!當然,這聽起來有些愚蠢,但它是可能的,而編寫 C++ 解析器的人必須考慮所有可能的輸入,甚至是愚蠢的。

  直到 C 成為已知之前,沒有任何辦法知道 C::const_iterator 到底是不是一個 type(類型),而當 template(模板)print2nd 被解析的時候,C 還不是已知的。C++ 有一條規則解決這個歧義:如果解析器在一個 template(模板)中遇到一個 nested dependent name(嵌套依賴名字),它假定那個名字不是一個 type(類型),除非用其它方式告訴它。缺省情況下,nested dependent name(嵌套依賴名字)不是 types(類型)。(對于這條規則有一個例外)

  記住這個,再看看 print2nd 的開頭:
template<typename C>void print2nd(const C& container)
{
 if (container.size() >= 2) {
  C::const_iterator iter(container.begin()); // this name is assumed to
  ... // not be a type
  這為什么不是合法的 C++ 現在應該很清楚了。iter 的 declaration(聲明)僅僅在 C::const_iterator 是一個 type(類型)時才有意義,但是我們沒有告訴 C++ 它是,而 C++ 就假定它不是。要想轉變這個形勢,我們必須告訴 C++ C::const_iterator 是一個 type(類型)。我們將 typename 放在緊挨著它的前面來做到這一點:

template<typename C> // this is valid C++
void print2nd(const C& container)
{
if (container.size() >= 2) {
typename C::const_iterator iter(container.begin());
...
}
}
  通用的規則很簡單:在涉及到一個在 template(模板)中的 nested dependent type name(嵌套依賴類型名)的任何時候,必須把單詞 typename 放在緊挨著它的前面。(重申一下,我待會兒要描述一個例外。)

  typename 應該僅僅被用于標識 nested dependent type name(嵌套依賴類型名);其它名字不應該用它。例如,這是一個取得一個 container(容器)和這個 container(容器)中的一個 iterator(迭代器)的 function template(函數模板):

template<typename C> // typename allowed (as is "class")
void f(const C& container, // typename not allowed
typename C::iterator iter); // typename required
  C 不是一個 nested dependent type name(嵌套依賴類型名)(它不是嵌套在依賴于一個 template parameter(模板參數)的什么東西內部的),所以在聲明 container 時它不必被 typename 前置,但是 C::iterator 是一個 nested dependent type name(嵌套依賴類型名),所以它必需被 typename 前置。

  "typename must precede nested dependent type names"(
typename 必須前置于嵌套依賴類型名)規則的例外是 typename 不必前置于在一個 list of base classes(基類列表)中的或者在一個 member initialization list(成員初始化列表)中作為一個 base classes identifier(基類標識符)的 nested dependent type name(嵌套依賴類型名)。例如:

template<typename T>
class Derived: public Base<T>::Nested { // base class list: typename not
 public: // allowed
  explicit Derived(int x)
  : Base<T>::Nested(x) // base class identifier in mem
  {
   // init. list: typename not allowed
    typename Base<T>::Nested temp; // use of nested dependent type
   ... // name not in a base class list or
  } // as a base class identifier in a
 ... // mem. init. list: typename required
};
  這樣的矛盾很令人討厭,但是一旦在經歷中獲得一點經驗,幾乎不會在意它。

  讓我們來看最后一個 typename 的例子,因為它在看到的真實代碼中具有代表性。假設我們在寫一個取得一個 iterator(迭代器)的 function template(函數模板),而且我們要做一個 iterator(迭代器)指向的 object(對象)的局部拷貝 temp,我們可以這樣做:
template<typename IterT>
void workWithIterator(IterT iter)
{
 typename std::iterator_traits<IterT>::value_type temp(*iter);
 ...
}
  不要讓 std::iterator_traits<IterT>::value_type 嚇倒你。那僅僅是一個 standard traits class(標準特性類)的使用,用 C++ 的說法就是 "the type of thing pointed to by objects of type IterT"(
被類型為 IterT 的對象所指向的東西的類型)。這個語句聲明了一個與 IterT objects 所指向的東西類型相同的 local variable(局部變量)(temp),而且用 iter 所指向的 object(對象)對 temp 進行了初始化。如果 IterT 是 vector<int>::iterator,temp 就是 int 類型。如果 IterT 是 list<string>::iterator,temp 就是 string 類型。因為 std::iterator_traits<IterT>::value_type 是一個 nested dependent type name(嵌套依賴類型名)(value_type 嵌套在 iterator_traits<IterT> 內部,而且 IterT 是一個 template parameter(模板參數)),我們必須讓它被 typename 前置。

  如果覺得讀 std::iterator_traits<IterT>::value_type 令人討厭,就想象那個與它相同的東西來代表它。如果像大多數程序員,對多次輸入它感到恐懼,那么就需要創建一個 typedef。對于像 value_type 這樣的 traits member names(特性成員名),一個通用的慣例是 typedef name 與 traits member name 相同,所以這樣的一個 local typedef 通常定義成這樣:

template<typename IterT> void workWithIterator(IterT iter)
{
 typedef typename std::iterator_traits<IterT>::value_type value_type;

 value_type temp(*iter);
 ...
}
  很多程序員最初發現 "typedef typename" 并列不太和諧,但它是涉及 nested dependent type names(嵌套依賴類型名)規則的一個合理的附帶結果。

  一些編譯器接受必需 typename 時它卻缺失的代碼;一些編譯器接受不許 typename 時它卻存在的代碼;還有少數的(通常是老舊的)會拒絕 typename 出現在它必需出現的地方。這就意味著 typename 和 nested dependent type names(嵌套依賴類型名)的交互作用會導致一些輕微的可移植性問題。

Things to Remember   
·在聲明 template parameters(模板參數)時,class 和 typename 是可互換的。
  
·用 typename 去標識 nested dependent type names(嵌套依賴類型名),在 base class lists(基類列表)中或在一個 member initialization list(成員初始化列表)中作為一個 base class identifier(基類標識符)時除外。

posted on 2007-05-09 11:47 譚文政 閱讀(427) 評論(0)  編輯 收藏 引用 所屬分類: C/C++
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美激情国产精品| 亚洲欧美一区二区在线观看| 久久亚洲风情| 久久久久久久高潮| 亚洲国产精品免费| 亚洲黄色一区二区三区| 欧美成人有码| 午夜精品一区二区三区在线播放 | 亚洲国产高清一区二区三区| 女女同性精品视频| 欧美日韩成人激情| 欧美一区二区性| 免费精品视频| 性久久久久久| 玖玖玖免费嫩草在线影院一区| 亚洲精品国产精品乱码不99按摩| 亚洲精品久久久蜜桃| 国产精品亚洲激情| 欧美a级一区二区| 国产精品超碰97尤物18| 另类激情亚洲| 欧美午夜精品久久久久久孕妇| 久久精品国产亚洲高清剧情介绍| 噜噜噜久久亚洲精品国产品小说| 在线视频欧美精品| 久久久久成人精品免费播放动漫| 一本久道综合久久精品| 午夜伦欧美伦电影理论片| 亚洲欧洲偷拍精品| 欧美一级久久| 亚洲欧美成人一区二区在线电影| 久久精品91久久久久久再现| 一本久道久久久| 久久久久成人精品| 欧美综合第一页| 欧美精品久久久久久| 久久久999成人| 国产精品国产三级国产普通话三级| 六月天综合网| 国产日韩精品入口| 一区二区三区免费网站| 91久久在线| 久久黄金**| 欧美日本高清一区| 亚洲成人在线网| 亚洲九九精品| 欧美在线视频一区| 欧美一区二区三区日韩| 欧美区视频在线观看| 欧美暴力喷水在线| 伊人久久大香线蕉av超碰演员| 亚洲图片欧美午夜| 亚洲性线免费观看视频成熟| 久久综合久久综合这里只有精品| 久久av最新网址| 国产精品久久久久久久电影| 亚洲另类黄色| 99在线视频精品| 欧美精品大片| 亚洲成在线观看| 亚洲精品国产精品乱码不99按摩 | 久久乐国产精品| 久久精品一区| 极品av少妇一区二区| 欧美在线观看视频一区二区| 久久er99精品| 国内自拍一区| 久久九九精品99国产精品| 久久精品视频免费| 一区二区三区在线看| 久久精品国产精品亚洲综合| 久久免费高清视频| 亚洲国产成人高清精品| 麻豆国产va免费精品高清在线| 欧美成人首页| av成人天堂| 欧美日韩另类丝袜其他| 中文亚洲视频在线| 久久精品99国产精品酒店日本| 国产一区二区三区四区五区美女| 欧美一级午夜免费电影| 免费日韩视频| 99视频精品免费观看| 欧美性一区二区| 欧美一区二区三区视频| 麻豆成人综合网| 99国产一区二区三精品乱码| 国产精品av免费在线观看 | 91久久极品少妇xxxxⅹ软件| 99精品福利视频| 国产日产亚洲精品| 久久午夜羞羞影院免费观看| 91久久国产自产拍夜夜嗨| 夜夜嗨av一区二区三区| 国产日韩精品久久久| 男女精品网站| 亚洲一区免费观看| 欧美不卡福利| 欧美一区二区三区四区在线观看地址 | 亚洲欧洲精品一区| 亚洲欧美中文日韩v在线观看| 国产一区二区高清视频| 欧美激情91| 久久久久国产精品一区二区| 亚洲人成啪啪网站| 国产日韩欧美一区| 欧美韩国在线| 久久久精品午夜少妇| 亚洲精品视频啊美女在线直播| 欧美在线综合| 一区二区三区高清视频在线观看| 韩国三级电影久久久久久| 欧美日韩在线亚洲一区蜜芽| 久久精品免费电影| 亚洲网站在线观看| 亚洲福利在线看| 老巨人导航500精品| 欧美一区二区播放| 日韩一区二区久久| 亚洲国产精品视频| 国产欧美一区二区三区另类精品| 欧美精品久久一区二区| 久久综合狠狠综合久久激情| 亚洲影音一区| 亚洲视频一区| 夜夜爽99久久国产综合精品女不卡| 麻豆精品一区二区综合av | 亚洲日本aⅴ片在线观看香蕉| 国产亚洲一区精品| 国产精品青草久久久久福利99| 欧美精品精品一区| 欧美精品激情| 欧美激情偷拍| 欧美精品在线观看一区二区| 欧美成人精品不卡视频在线观看| 久久激情五月激情| 久久久久久久久久久一区| 欧美一区综合| 久久精品日产第一区二区| 欧美一区二区私人影院日本| 亚洲综合激情| 欧美亚洲在线播放| 性欧美暴力猛交69hd| 先锋影音久久久| 亚洲欧美制服另类日韩| 午夜视频在线观看一区二区| 亚洲欧美bt| 久久精品国产欧美激情| 久久日韩精品| 免费看亚洲片| 欧美日韩中文| 国产视频一区二区在线观看| 国产一区二区三区最好精华液| 国产一区二区三区久久| 国产香蕉97碰碰久久人人| 激情一区二区三区| 亚洲日本乱码在线观看| 在线中文字幕日韩| 亚洲欧美另类在线| 久久久精品日韩欧美| 欧美xart系列在线观看| 亚洲国产日韩在线| 亚洲淫性视频| 久久久久久久久久久久久女国产乱 | 激情亚洲成人| 99国产精品99久久久久久| 在线天堂一区av电影| 亚洲欧美日韩综合一区| 久久精品国产免费观看| 久久久水蜜桃av免费网站| 欧美国产一区视频在线观看| 亚洲精品欧美日韩| 午夜精品久久久久久99热| 久久久蜜桃一区二区人| 欧美精品 日韩| 国产精品视频网站| 女同性一区二区三区人了人一| 欧美欧美全黄| 韩国av一区| 亚洲视频在线观看网站| 久久婷婷久久一区二区三区| 亚洲国产成人精品久久| 中文av字幕一区| 久久亚洲国产成人| 国产精品久久久久一区| 亚洲黄色精品| 欧美一区二区三区在| 亚洲激情午夜| 久久黄色影院| 国产精品久久999| 91久久久久久| 久久久久9999亚洲精品| 亚洲精品国精品久久99热一| 亚洲欧美精品在线观看| 欧美经典一区二区三区| 国内成人精品2018免费看| 亚洲天堂男人| 亚洲黑丝在线| 玖玖精品视频| 激情婷婷久久|