2011-10-05 182 views
0

我正在學習C++概念 - 模板專業化和部分模板專業化。有一個代碼如下,我想了解,所以我正確地得到這些概念。查詢C++模板專業化和部分模板專業化

我有一個關於這幾個問題,這些問內嵌如下:

template <typename T, int nSize> 
class Buffer 
{ 
private: 
    T m_atBuffer[nSize]; 

public: 
    T* GetBuffer() 
    { 
     return m_atBuffer; 
    } 

    T& operator[](int nIndex) 
    { 
     return m_atBuffer[nIndex]; 
    } 
}; 


template <typename T, int nSize> 
void PrintBufferString(Buffer<T, nSize> &rcBuf) 
{ 
    std::cout << rcBuf.GetBuffer() << std::endl; 
} 


void PrintBufferString(Buffer<char, 10> &rcBuf) 
{ 
    std::cout << rcBuf.GetBuffer() << std::endl; 
} 


int main() 
{ 
    // declare a char buffer 
    Buffer<char, 13> cChar10Buffer; 

    // copy a value into the buffer 
    strcpy(cChar10Buffer.GetBuffer(), "Ten"); 

    PrintBufferString(cChar10Buffer); //This prints "Ten" 

    // declare an int buffer 
    Buffer<int, 10> cInt10Buffer; 

    // copy values into the buffer 
    for (int nCount=0; nCount < 10; nCount++) 
     cInt10Buffer[nCount] = nCount; 

    PrintBufferString(cInt10Buffer); // This prints address of the buffer- m_atBuffer for object cInt10Buffer 

    return 0; 
} 

所以,如果我們通過比焦炭的模板函數PrintBufferString(其它任何類型的),它的cout打印緩衝區的地址,而不是字符串,這是一個問題。

因此,爲了解決這個問題,它說,我們定義一個模板特如下所示,以確保char類型的只有陣列可被傳遞到PrintBufferString()

void PrintBufferString(Buffer<char, 10> &rcBuf) 
{ 
    std::cout << rcBuf.GetBuffer() << std::endl; 

} 

問題1:所以通過爲模板類型參數int傳遞一個Buffer對象,但它編譯好了,我認爲它應該給出編譯錯誤,當我試圖調用

PrintBufferString(cInt10Buffer)時,應該給出編譯錯誤。那個怎麼樣?那麼爲char類型添加此模板專門化有什麼用處?

我想加入char類型的模板專業化,我們不能把它用於任何其他類型的

問題2:然後,我主要是下面添加了另一個函數調用:

Buffer<char, 11> cChar11Buffer; 
strcpy(cChar11Buffer.GetBuffer(), "Eleven"); 

PrintBufferString(cChar11Buffer); // 

它說這會給編譯錯誤,但它在MS-Visual C++ 2010 Express.IT甚至執行罰款和打印「十」「一些地址」「十一」罰款。

它爲什麼編譯和執行良好?因爲我知道類緩衝區類不同於類緩衝區,並且函數 PrintBufferString()接受類類型爲Buffer的對象,並且這兩者不能混合?

問題3:然後,它接着,如下定義模板偏特來處理的情況下,當char類型的對象緩衝區,但任何大小可以傳遞類對象類型,然後將其傳遞給函數PrintBufferString ();

template<int nSize> 
void PrintBufferString(Buffer<char, nSize> &rcBuf) 
{ 
    std::cout << rcBuf.GetBuffer() << std::endl; 
} 

現在還印「十」「十一」像以前一樣。那麼這個部分模板專業化實現了什麼特殊?這不是部分模板專業化的好例子嗎?從這個例子來看,這個概念並不是很清楚。

回答

2

C++沒有/支持功能模板的部分專業化,僅限於類模板。因此,你所看到的代碼都與你(至少說你)想要學習/理解的內容有關。

一個部分專業類模板將是這樣的:

template <class T, class U> // the "base" (unspecialized) template 
class X { 
}; 

template <class T>   // partial specialization for `X<whatever, int>` 
class X<int> { 
}; 

注意(在這裏)的非專業模板,必須先在部分專用的模板。

+0

此代碼不會編譯。部分專業化應該像這樣'template class X '。 – yanpas

1

在你的第一種情況下,函數不是專門化的,它只是超載。

如果您想要阻止除char之外的其他類型,只需定義問題3中的版本即可。只要您不通過模板<>將函數作爲前綴,它就不會被視爲部分特化。

您可以定義使用帶有一些固定模板參數的模板類型的函數。