難度:
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
先來一道思考題
template<typename T, T* p>
struct A
{};
假若有個int類型的對象i,那麼對於下面這段代碼
A<int, &i> obj;
這個是合法的嗎?
答: A<int, &i> obj; 可能合法 或 可能不合法。
什麼東西可以當作模板的參數呢? 部分的內建類型和用戶類型,和部分非類型的東西也可以當作模板參數。
非類型模板參數的一個要求是,編譯器能在編譯期就能把參數確定下來。換言之,就是非類型的模板參數必須是個編譯期常量。
判斷這句是否合法得看&i返回的是不是一個編譯期常量。當i是全局或靜態對象,那麼這個語句就是正確的,因爲全局和靜態對象的內存分配發生在編譯期,所以這樣一來i的地址(&i的值)就是可以被確定的。
現在把這個程序補全成合法的
int i;
int main(){
A<int, &i> obj;
}
如果這個模板的第二個參數是引用,那麼也是同理。不過值得注意的是,這些非類型、非引用模板參數都不是左值!
最後,可以當作非類型參數的東西有 整數、enum類型、指針、引用。
其中局部的用戶自定義類型(Local Class)不能作爲模板參數。這是因爲局部類沒有外部連接。舉個例子
template<typename T>
class TEST{};
void fun1()
{
struct X{};
TEST<X> a;
}
void fun2()
{
struct X{};
TEST<X> a;
}
上面的TEST<X> a;是同一個東西嗎? 由於沒有外部連接,它們就是同一個東西,而程序員的本意是兩個局部類X是兩個不同的類定義,也認爲TEST<A>是兩個不同的模板實例。
對於局部類,可以說它是 健全的C++類型系統的一個畸形兒。沒有外部連接導致它不能擁有static data members,不能擁有template member functions等等。
//The End