青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
Where there is a dream ,there is hope
C++博客
::
首頁
::
聯系
::
聚合
::
管理
64 Posts :: 0 Stories :: 8 Comments :: 0 Trackbacks
常用鏈接
我的隨筆
我的評論
我參與的隨筆
留言簿
(1)
給我留言
查看公開留言
查看私人留言
我參與的團隊
隨筆分類
C#(2)
C/C++(19)
EFFECTIVE-STL學習筆記(3)
Mono
monodevelop
TCP/IP(1)
翻譯文章(4)
算法/數據結構(1)
折騰UBUNTU(2)
職業人生(1)
隨筆檔案
2011年11月 (1)
2011年10月 (7)
2011年9月 (2)
2011年8月 (7)
2011年7月 (3)
2011年6月 (5)
2011年4月 (2)
2011年3月 (5)
2011年2月 (8)
2011年1月 (1)
2010年12月 (7)
2010年11月 (9)
2010年10月 (4)
2010年7月 (3)
收藏夾
生活思考(1)
C++
C#講師-設計模式-數據結構
范懷宇
韓湘子
專門解決各種C++疑難雜癥
搜索
最新評論
1.?re: 匿名空間
.就空間看快樂
--何霞飛
2.?re: 匿名空間
u厲害
--何霞飛
3.?re: 服務器設計-轉
這種文章挺少的噢。不是做服務器的,多了解一些總是好的。設計真是一門有意思的學問。
--K.V
4.?re: josephon問題
不過這個模擬過程非常不好,對于100000以上的人數來說簡直就是悲劇。。。
--Husiwa
5.?re: 簡潔的字符串連接函數
@木頭奎
的確有缺點,但這個函數的實現過程還是有其發作的
--Husiwa
閱讀排行榜
1.?轉載:vector find(2391)
2.?vector 查找指定元素(1790)
3.?C#結構體序列化(1280)
4.?windows.h與winsock2.h的包含順序(1174)
5.?模板類靜態變量初始化(1141)
評論排行榜
1.?匿名空間(2)
2.?簡潔的字符串連接函數(2)
3.?C++指針探討 (一)數據指針(1)
4.?服務器設計-轉(1)
5.?Orx教程--4.動畫(1)
轉載 typename
C++箴言:理解typename的兩個含義 問題:在下面的 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(嵌套依賴名字)。
print2nd 中的另一個 local variable(局部變量)value 具有 int 類型。int 是一個不依賴于任何 template parameter(模板參數)的名字。這樣的名字以 non-dependent names(非依賴名字)聞名。(我想不通為什么他們不稱它為 independent names(無依賴名字)。如果,像我一樣,你發現術語 "non-dependent" 是一個令人厭惡的東西,你就和我產生了共鳴,但是 "non-dependent" 就是這類名字的術語,所以,像我一樣,轉轉眼睛放棄你的自我主張。)
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 std::iterator_traits<IterT>::value_type 需要多少時間?
作為結束語,我應該提及編譯器與編譯器之間對圍繞 typename 的規則的執行情況的不同。一些編譯器接受必需 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 2011-06-16 10:29
IT菜鳥
閱讀(116)
評論(0)
編輯
收藏
引用
只有注冊用戶
登錄
后才能發表評論。
網站導航:
博客園
IT新聞
BlogJava
博問
Chat2DB
管理
Copyright @ IT菜鳥
Powered by:
.Text
and
ASP.NET
Theme by:
.NET Monster
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
欧美高清视频一区二区
|
国产亚洲福利
|
欧美黑人在线播放
|
欧美视频国产精品
|
国产欧美日韩亚州综合
|
有码中文亚洲精品
|
亚洲精品一级
|
亚洲欧美日韩一区二区三区在线观看
|
亚洲一区二区三区四区中文
|
国产精品免费视频xxxx
|
国产一区二区三区久久
|
亚洲欧洲一二三
|
欧美一区二区啪啪
|
亚洲成人在线网站
|
中文在线一区
|
久久久亚洲综合
|
欧美午夜免费影院
|
亚洲国产精品一区制服丝袜
|
一区二区三区日韩在线观看
|
久久久精品999
|
亚洲精品在线免费
|
久久久久久久久伊人
|
国产精品国产
|
亚洲免费观看高清完整版在线观看熊
|
亚洲自拍三区
|
亚洲人成7777
|
久久综合国产精品
|
国产欧美日韩麻豆91
|
99精品99久久久久久宅男
|
久久久久久999
|
亚洲婷婷免费
|
欧美另类专区
|
亚洲欧洲久久
|
欧美v日韩v国产v
|
午夜精品偷拍
|
国产精品女同互慰在线看
|
亚洲精品欧美日韩
|
牛人盗摄一区二区三区视频
|
午夜精品久久久久
|
国产精品每日更新
|
一本色道久久综合亚洲精品不卡
|
亚洲午夜免费视频
|
亚洲国产小视频在线观看
|
久久久亚洲影院你懂的
|
国产一区二区欧美日韩
|
欧美亚洲免费电影
|
亚洲影院免费观看
|
国产精品久久久久久亚洲调教
|
亚洲精品欧美日韩
|
亚洲国产日日夜夜
|
欧美va天堂
|
亚洲精品系列
|
最新国产乱人伦偷精品免费网站
|
久久久噜噜噜久久中文字免
|
极品中文字幕一区
|
免费欧美在线视频
|
久热精品视频在线观看一区
|
亚洲高清久久久
|
亚洲国产精品福利
|
欧美日韩国产va另类
|
中文av一区特黄
|
亚洲午夜高清视频
|
国产伦精品一区二区三区视频孕妇
|
亚洲尤物在线
|
亚洲欧美日韩在线高清直播
|
国产日韩欧美麻豆
|
麻豆精品国产91久久久久久
|
美腿丝袜亚洲色图
|
在线综合欧美
|
香蕉国产精品偷在线观看不卡
|
国产丝袜美腿一区二区三区
|
久久先锋影音
|
欧美精品激情在线观看
|
亚洲亚洲精品在线观看
|
亚洲男女毛片无遮挡
|
国产一区二区丝袜高跟鞋图片
|
久久午夜国产精品
|
欧美精品一二三
|
欧美一区二区视频在线
|
久久综合电影
|
亚洲资源在线观看
|
久久久久国产精品www
|
亚洲人精品午夜在线观看
|
一本色道久久综合狠狠躁篇怎么玩
|
小黄鸭视频精品导航
|
国产一区二区三区在线播放免费观看
|
久久久久久欧美
|
在线日韩电影
|
在线亚洲欧美
|
一区免费观看
|
一本久道久久综合狠狠爱
|
国产日韩一区二区三区在线
|
亚洲电影免费在线观看
|
国产精品一区二区你懂的
|
美女视频黄a大片欧美
|
欧美日韩久久
|
久久综合九色综合网站
|
欧美揉bbbbb揉bbbbb
|
蜜桃av综合
|
国产精品久久久99
|
亚洲国产精品国自产拍av秋霞
|
国产精品午夜春色av
|
亚洲第一在线综合网站
|
国产自产在线视频一区
|
99成人精品
|
亚洲精选一区
|
久久夜色精品国产噜噜av
|
亚洲欧美经典视频
|
欧美精品午夜视频
|
欧美高清不卡
|
伊人精品在线
|
午夜精品久久久久久久99黑人
|
91久久在线播放
|
久久精品综合网
|
欧美在线观看一区二区三区
|
欧美日韩亚洲综合一区
|
亚洲激情一区二区
|
亚洲激情电影中文字幕
|
久久九九电影
|
久久久www免费人成黑人精品
|
国产精品草草
|
亚洲日本欧美日韩高观看
|
在线观看成人av电影
|
欧美在线观看日本一区
|
欧美一区在线视频
|
国产精品日韩在线一区
|
在线中文字幕不卡
|
亚洲香蕉伊综合在人在线视看
|
美女视频黄免费的久久
|
免费国产一区二区
|
亚洲国产天堂网精品网站
|
久久亚洲春色中文字幕久久久
|
久热re这里精品视频在线6
|
国产美女精品视频免费观看
|
亚洲欧美电影院
|
久久久国产91
|
在线高清一区
|
久久精品国产综合精品
|
欧美在线free
|
国产日韩欧美在线视频观看
|
午夜欧美大尺度福利影院在线看
|
欧美一乱一性一交一视频
|
国产欧美日韩在线视频
|
小黄鸭精品aⅴ导航网站入口
|
西西裸体人体做爰大胆久久久
|
欧美日韩中文另类
|
中文高清一区
|
欧美亚洲一区
|
国产中文一区二区
|
久久久夜夜夜
|
欧美电影美腿模特1979在线看
|
国产日韩欧美在线观看
|
亚洲欧美一区二区在线观看
|
午夜伦理片一区
|
狠狠色狠狠色综合日日tαg
|
亚洲尤物视频网
|
久久久亚洲高清
|
亚洲国产精品久久久久
|
欧美激情一区二区三区不卡
|
一本色道88久久加勒比精品
|
99精品视频免费全部在线
|
欧美日韩视频第一区
|
在线亚洲欧美
|
欧美顶级少妇做爰
|
最近看过的日韩成人
|
欧美日韩另类字幕中文
|
欧美在线网址
|
欧美午夜在线一二页
|
久久精品国产99国产精品澳门
|
亚洲精品一区二区在线观看
|
欧美福利视频一区
|
99国产一区
|
久久亚洲美女
|
亚洲婷婷国产精品电影人久久
|
国产精品午夜视频
|
欧美91精品
|
欧美一级片一区
|
亚洲人成在线免费观看
|
久久久久网站
|
亚洲女性裸体视频
|
亚洲精品视频在线看
|
韩国三级电影一区二区
|
欧美日韩综合在线免费观看
|
久久性色av
|
久久er精品视频
|
亚洲影院高清在线
|
亚洲精品一区二区三区av
|
久久伊人免费视频
|
欧美一区二区三区在
|
一本色道久久综合狠狠躁篇怎么玩
|
亚洲欧美激情精品一区二区
|
久久精品91久久香蕉加勒比
|
有码中文亚洲精品
|
欧美午夜一区二区
|
另类欧美日韩国产在线
|
羞羞答答国产精品www一本
|
亚洲国产精品一区二区尤物区
|
欧美一区二区三区另类
|
一本在线高清不卡dvd
|
亚洲高清不卡av
|