I am studying C++ concepts - Template specialization and Partial template specialization. Have a code as below, which I want to understand so I get these concepts correctly.
I have few questions regarding that, which are asked inline below:
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;
}
So if we pass any type other than char to the templated function PrintBufferString() it cout prints the address of the buffer rather than the string, which is a problem.
So to solve this problem, it said that we define a template specialization as shown below, to ensure that only arrays of type char can be passed to PrintBufferString()
void PrintBufferString(Buffer<char, 10> &rcBuf)
{
std::cout << rcBuf.GetBuffer() << std::endl;
}
Question 1: So adding this template specialization for function PrintBufferString (), I thought that it should have given a compilation error when I tried to call
PrintBufferString(cInt10Buffer) by passing a Buffer object with templated type parameter int, but it compiled fine? How is that? Then what is the use of adding this template specialization for type char?
I thought adding a template specialization for type char, we cannot call it for any other type
Question 2: Then I added another function call as below in main:
Buffer<char, 11> cChar11Buffer;
strcpy(cChar11Buffer.GetBuffer(), "Eleven");
PrintBufferString(cChar11Buffer); //
It said this would give compilation error, but it compiled fine in MS -Visual C++ 2010 Express.IT even executed fine and printed "Ten" "some address" "Eleven".
Why did it compile and execute fine? Because I had understanding that type a Class Buffer is different than Class Buffer, and function PrintBufferString() accepts object of class type Buffer, and both of these cannot be intermixed?
Question 3: Then it went on to define a partial template specialization as below to handle the case when a object buffer of type char but any size can be passed Class object type, which is then passed to the function PrintBufferString();
template<int nSize>
void PrintBufferString(Buffer<char, nSize> &rcBuf)
{
std::cout << rcBuf.GetBuffer() << std::endl;
}
Now also it printed "Ten" "Eleven" just as before. So what special did this partial template specialization achieve? Is this not a good example of partial template specialization? The concept is not very clear to me, from this example.