語法功能模板爲什麼C++模板參數應該聲明爲類類型?
template <**class** T, ...>
returntype functionname(arguments)
{
.....
.....
}
的我有兩個問題嗎?
- 爲什麼模板參數應被聲明爲一個類的類型?(即 與使用class關鍵字)
- 當我們宣佈它作爲一個類類型,那麼什麼東西編譯器 會做什麼?
語法功能模板爲什麼C++模板參數應該聲明爲類類型?
template <**class** T, ...>
returntype functionname(arguments)
{
.....
.....
}
的我有兩個問題嗎?
根據標準,有兩個關鍵字:class
和typename
。您可以在模板定義中使用它們中的任何一個。兩者具有相同的含義:當您在模板定義中編寫class
(或typename
)時,這意味着模板的用戶必須將類型作爲模板參數傳遞給模板;這並不意味着什麼。如果它是一個函數模板,那麼模板參數可能是從參數推導(在某些情況下)到該函數。
這是通常在template
參數中使用class
引起的混淆。
那class
事情跟班沒有關係;它只是說模板接受一個類型模板參數(而不是整數模板參數),它可以是任何類型,不僅僅是類。
那麼,他們爲什麼選擇class
?因爲他們必須使用在任何C++程序中肯定沒有使用的關鍵字,並且或多或少「聽起來不錯」,並且class
沒問題,因爲它已經是C++中的保留關鍵字了。
請注意,class
還有一個替代方案:typename
關鍵字。他們完全相同,但我認爲typename
更清晰,因爲該名稱只是說「以下是一種類型的爭論」,而不會讓你認爲它必須是一個類。
爲什麼兩種語法都允許?因爲typename
關鍵字在語言後面(當他們發現有必要添加另一個關鍵字以消除模板中的某些聲明)時,纔會引入該關鍵字;然後,對「template
」參數聲明也進行了「翻新」。保留了class
關鍵字的這種用法,以便與在此期間編寫的程序/文檔保持兼容。
模板參數中的class和typename之間沒有語義上的區別。
(C++ 11,§14。1¶2)
「一些角落案件」?嗯,也許我過度使用模板,我必須經常寫'typedef typename TemplateParamClass :: nestedClass ShortName'。 – leftaroundabout 2012-04-22 14:06:07
@leftaroundabout:你說得對,說這是一個角落的案例實際上有點太多了,但是在學習模板時不會立即升高。不過,我改變了一下措辭。 – 2012-04-22 14:10:46
(1)爲什麼模板參數應被聲明爲一個類的類型?
不是真的完全。您也可以使用typename
。 :)
更重要的是,您也可以將某些類型的const
對象聲明爲參數。例如
template<int I> // <---- 'I' is not a class/typename
class A { ... };
...
A<3> obj;
(2)當我們宣佈它作爲一個類類型,那麼什麼東西編譯器 會做什麼?
其實不多。
但是,當你調用它的對象時,編譯器檢查類型實際上是一個類型名稱。例如
template<class T>
class A { ... }; // ok ... not much to check
...
A<int> obj1; // compiler checks if 'int' is a type ---> yes
A<3> obj2; // compiler checks if '3' is a type ---> no
因爲這是語言定義告訴你使用的詞。 'T類'在這裏意味着'T是某種類型的名字',而不是'T是某個類的名字'。
我相信理由在於希望不添加另一個保留字。
但是,該語言最終還添加了另一個保留字:您可以等同地說'typename T'。
注意,您可以通過標準的類型template
,不僅類:
template <class T, int N> class mysequence {..};
所以,class
關鍵字這裏告訴編譯器把T作爲類。 N被視爲整數。
那麼,**某些**標準類型。 – 2012-04-22 14:05:29
因爲標準所以如此 – 2012-04-22 13:58:16
@VJovic:廢話。標準沒有說「模板參數應該被聲明爲一個類類型」,但它必須用'class' ***關鍵字***聲明。另外,說「因爲標準這麼說」,根本無助於理解標準化過程中選擇的理由。 – 2012-04-22 14:07:35