Jason Jason - 12 days ago 9
C++ Question

Template multiple definition issue

I want to use some of my own template classes within my dll project. In order to do so it was suggested here that I still separate my class template declaration from its definition by including the definition of my class's header file (as a .inl file). The class I'm trying to accomplish this with is my own vector class which will just wrap the std::vector class. Example of class setup below:

Vector.h

#pragma once
#include <vector>

namespace BlazeFramework
{
template<typename type>
class Vector
{
public:
Vector();
Vector(int size);
~Vector();

private:
std::vector<type> _collectionOfItems;
};
}

#include "Vector.inl"


Vector.inl

#include "Precompiled.h"
#include "Vector.h"

namespace BlazeFramework
{
template<typename type>
Vector<type>::Vector()
{
}

template<typename type>
Vector<type>::Vector(int size) : _collectionOfItems(_collectionOfItems(size, 0))
{
}

template<typename type>
Vector<type>::~Vector()
{
}
}


When I first tried this I got the errors saying "Function Template has already been defined". I figured this was due to my .inl file including the "Vector.h" header at the top so I removed that. However, I'm now getting the errors,

"unrecognizable template declaration/definition".

How do I resolve this issue so I can still separate my class template definitions from their declarations?

Answer

One solution to keep the definition and implementation templates in separate files is to explicitly instantinate the required templates in the source file. For example:

template class Vector<int>;
template class Vector<float>;

In this case the #include "Vector.inl" from the header should be removed.

If you don't like this approach you could stick to the #include. However, keep in mind that the Vector.inl file should not be compiled as a regular source. If it did, you would get a redefinition of template... kind of error.

Although, keep in mind that in general template classes are best to be compact, simple and designed to be held inside the header file - since this is the hint the compieler uses to generate the actual classes.

I would suggest reading about the topic in the following posts:

Additionally, you probably should look at the initialization list in the constructor - seems to be incorrect.