|
Partial Template Specialization
Submitted by |
Template programming with C++ is always hell, compilers seem to enjoy making
your life difficult when you try to use them, but just think about it in
this way: they are merely defending themselves! , you are trying to make
them doing all that nasty and repetitive work that you dont want to do,
and perhaps they have a point in being that annoying
However we still have to keep on fighting them, and there are some very
useful template features, such as partial template specialization, that may
be required in some context and arent supported at all by most compilers,
for instance lets consider a very simplistic container template such as
this:
template <typename ElementType, int NUM_ELEMENTS
class SillyContainer
{
ElementType m_data[NUM_ELEMENTS];
public:
void setElement(int index, const ElementType& element)
{
m_data[index] = element;
}
}; |
This seems quite straightforward, but right now think of using it with a
complex data type, such an struct containing pointers (SillyVertexBuffer),
that havent any kind of operator= or copy constructor overload, and you
have to deep-copy
this simple container wouldnt work
if you are using
this container for that class youll have to create an partial
specialization (just the type) of the template being able to deal with it
properly:
struct SillyVertexBuffer
{
typedef float Vertex[3];
int numVertices;
Vertex* vertexPtr;
};
template <int NUM_ELEMENTS
class SillyContainer<SillyVertexBuffer, NUM_ELEMENTS
{
SillyVertexBuffer m_data[NUM_ELEMENTS];
public:
void setElement(int index, const SillyVertexBuffer& svb)
{
m_data[index].numVertices = svb.numVertices;
memcpy(m_data[index].verticesPtr, svb.verticesPtr, \
svb.numVertices*sizeof(SillyVertexBuffer::Vertex));
}
}; |
But this wouldnt work, because of the lack of support for partial template
specialization. Fortunately there is a workaround, using template functions:
template <typename ElementType
static void deepCopy(ElementType& dst, const ElementType& src)
{
dst = src;
}
template <
static void deepCopy<SillyVertexBuffer(SillyVertexBuffer& dst, const
SillyVertexBuffer& src)
{
dst.numVertices = src.numVertices;
memcpy(dst.vertexPtr, src.vertexPtr, \
src.numVertices*sizeof(SillyVertexBuffer::Vertex));
}
template <typename ElementType, int NUM_ELEMENTS
class SillyContainer
{
ElementType m_data[NUM_ELEMENTS];
public:
void setElement(int index, const ElementType& element)
{
deepCopy(m_data[index], element);
}
}; |
That recursive template instantiation policy should be powerful enough to
deal with any other problem related with partial specialization. If you
found any particular case where it isnt please let me know.
Matt
|
The zip file viewer built into the Developer Toolbox made use
of the zlib library, as well as the zlibdll source additions.
|