This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

| 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.

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.