查询C ++模板专业化和部分模板专业化

时间:2011-10-05 20:57:40

标签: c++ templates

我正在学习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(),那么cout将打印缓冲区的地址而不是字符串,这是一个问题。

所以为了解决这个问题,它说我们定义了一个模板特化,如下所示,以确保只有char类型的数组可以传递给PrintBufferString()

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

}

问题1:因此,为函数PrintBufferString()添加此模板特化,我认为在我尝试调用时它应该给出了编译错误

PrintBufferString(cInt10Buffer)通过传递带有模板化类型参数int的Buffer对象,但它编译得很好?那个怎么样?那么为char类型添加这个模板特化有什么用呢?

我想为类型char添加模板特化,我们不能为任何其他类型调用它

问题2:然后我在main中添加了另一个函数调用:

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

PrintBufferString(cChar11Buffer); //

它说这会产生编译错误,但它在MS -Visual C ++ 2010 Express中编译得很好。即使执行得很好并打印“十”“一些地址”“十一”。

为什么编译和执行正常?因为我已经理解类型的缓冲区与类缓冲区和函数的不同  PrintBufferString()接受类型为Buffer的对象,这两个都不能混用?

问题3:然后继续定义如下的部分模板特化,以处理类型为char但任何大小的对象缓冲区可以传递Class对象类型的情况,然后传递到函数PrintBufferString();

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

现在它也像以前一样打印“十”“十一”。那么这个部分模板专业化有什么特别之处呢?这不是部分模板专业化的好例子吗?从这个例子来看,这个概念对我来说并不是很清楚。

2 个答案:

答案 0 :(得分: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> {
};

请注意(如此处)非专业化模板必须位于部分专用模板之前。

答案 1 :(得分:1)

在你的第一种情况下,该功能不是专业化,它只是重载。

如果你想要阻止除char之外的其他类型,只需定义问题3中的版本。只要你没有通过模板&lt;&gt;为函数添加前缀,就不会将其视为部分特化。

您可以定义使用带有一些固定模板参数的模板类型的函数。