1.關鍵字typename
在C++標準化過程中,引入關鍵字typename是為了說明:模板內部的標識符可以是一個類型,譬如下面的例子:
template<typename T>
class MyClass{
typename T::SubType * ptr;
...
};
template <class T>
class MyClass
{
typename T::SubType 8 ptr;
//...
}
SubType成為一個型別的條件是,任何一個用來取代T的類型,
其內部都必須提供一個內部型別(inner type)SubType,例如
MyClass<Q> x;
必要條件是型別Q有如下的內部型別定義:
class Q{
typedef int SubType;
//...
}
或者
class Q{
class SubType;
}
2.template構造
考慮下面標準bieset模板的例子
template<int N>
void printBitset(std::bitset<N> const& bs)
{
std::cout<<bs.template to_string<char,char_traits<char>,allocator<char>>();
}
只有編輯器判斷小於符號<之前,存在依賴於模板參數的構造,才會出現這種問題。
3.模板的模板參數
template<typename T,
typename <typename ELEM,
typename ALLOC = std::allocator<ELEM>>
class CONT = std::deque>
class Stack{
private:
CONT<T> elems;
...
}
4.零初始化
對於int、double或者指標等基本類型,並不存在用一個有用的預設值來對他們進行初始化的預設建構函式,任何
未被初始化的局部變數都具有一個不確定的值
藉助如下代碼,我們可以確保對象已經執行了適當的預設初始化,即使對內建類型對象也是如此
template <typename T>
void Foo()
{
T x=T();
}
5.用字串做為函數模板的實參
把字串傳給模板的引用參數會導致出人意料的結果,考慮下面的程式:
#include <string>
template <typename T>
inline T const& max(T const& a,T const& b)
{
return a>b?b:a;
}
int main()
{
std::string s;
::max("apple","peach");//ok,相同類型的實參
::max("apple","tomato");//error,不同的類型實參
}
解釋:"apple"的類型為char const[6],"peach"的類型為char const[6],"tomato"的類型為char const[7]
-------------------------------------------------------
1.
成員函數模板不能被聲明為虛函數,模板類的普通成員可以使虛函數
2.
模板實參的一個普遍約束是:在程式建立時,編譯器或連結器要能夠確定實參的值,如果實參的值等到運行時才能確定(譬如,局部變數的地址),就不符合模板是在程式建立時初始化的概念了
另一方面,有些常值不能作為有效地非類型實參,這些類型包括:null 指標常量,浮點型值