Запрос о специализации шаблона C ++ и частичной специализации шаблона - PullRequest
0 голосов
/ 06 октября 2011

Я изучаю концепции 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;
}

Теперь также напечатано «Десять», «Одиннадцать», как и раньше.Так чего же удалось достичь этой частичной специализации?Разве это не хороший пример частичной специализации шаблона?Концепция не очень понятна для меня из этого примера.

Ответы [ 2 ]

2 голосов
/ 06 октября 2011

C ++ не имеет / поддерживает частичную специализацию шаблонов функций, только шаблонов классов. Таким образом, ни один из кодов, которые вы просматриваете, не имеет отношения к тому, что вы (по крайней мере, говорите) хотите изучать / понимать вообще.

Частично специализированный шаблон класса будет выглядеть примерно так:

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

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

Обратите внимание, что (как здесь) неспециализированный шаблон должен предшествовать частично специализированному шаблону.

1 голос
/ 06 октября 2011

В первом случае эта функция не является специализацией, она просто перегружена.

Если вы хотите запретить использование другого типа, кроме char, просто определите версию в вопросе 3. Пока вы не префиксируете свою функцию шаблоном <>, она не будет считаться частичной специализацией.

Вы можете определить функцию, которая использует типы шаблонов с некоторым фиксированным аргументом шаблонов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...