Я изучаю концепции 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;
}
Так что, если мы передадимлюбой тип, отличный от char, для шаблонной функции PrintBufferString (), которую он может печатать адрес буфера, а не строку, что является проблемой.
Поэтому, чтобы решить эту проблему, он сказал, что мы определяем специализацию шаблонакак показано ниже, чтобы гарантировать, что только функции типа char могут быть переданы в PrintBufferString ()
void PrintBufferString(Buffer<char, 10> &rcBuf)
{
std::cout << rcBuf.GetBuffer() << std::endl;
}
Вопрос 1: Поэтому, добавив эту специализацию шаблона для функции PrintBufferString (), я подумалчто он должен был выдать ошибку компиляции, когда я попытался вызвать
PrintBufferString (cInt10Buffer), передав объект Buffer с параметром шаблонного типа int, но он скомпилирован нормально?Как так?Тогда какой смысл добавлять эту специализацию шаблона для типа char?
Я подумал, добавив шаблонную специализацию для типа char, мы не можем вызвать его для любого другого типа
Вопрос 2: Затем я добавил еще один вызов функции, как показано ниже в main:
Buffer<char, 11> cChar11Buffer;
strcpy(cChar11Buffer.GetBuffer(), "Eleven");
PrintBufferString(cChar11Buffer); //
Было сказано, что это приведет к ошибке компиляции, но он прекрасно скомпилирован в MS-Visual C ++ 2010 Express.IT, даже выполнил штраф и напечатал «Десять», «некоторый адрес», «Одиннадцать».
Почему он компилируется и выполняется нормально?Потому что я понимал, что тип Class Buffer отличается от Class Buffer, и функция PrintBufferString () принимает объект типа Buffer класса, и оба они не могут быть смешаны?
Вопрос 3: Затем он продолжил определять частичную специализацию шаблона, как показано ниже, чтобы обработать случай, когда объектный буфер типа char, но любого размера может быть передан типу объекта Class, который затем передается в функцию PrintBufferString ();
template<int nSize>
void PrintBufferString(Buffer<char, nSize> &rcBuf)
{
std::cout << rcBuf.GetBuffer() << std::endl;
}
Теперь также напечатано «Десять», «Одиннадцать», как и раньше.Так чего же удалось достичь этой частичной специализации?Разве это не хороший пример частичной специализации шаблона?Концепция не очень понятна для меня из этого примера.