I am new to template programming and trying to implement a simple toy template class with Visual Studio 2010.
For the sake of clarity, I would like to split the code between a header and a source file:
//b.h
#ifndef B_H
#define B_H
template <class T>
class b
{
public:
b();
~b();
};
#include "b.cpp"
#endif
//b.cpp
#include "stdafx.h"
#include "b.h"
template <class T>
b<T>::b( ) { }
template <class T>
b<T>::~b() { }
The VS2010 compiler throws two C2995 errors. The constructor and destructor seem to be already defined in the header.
1>------ Operación Generar iniciada: proyecto: Tlib, configuración: Debug Win32 ------
1>Compilando...
1>b.cpp
1>c:\users\jacques\documents\visual studio 2008\projects\tlib\tlib\b.cpp(5) : error C2995: 'b<T>::b(void)' : ya se ha definido la plantilla de función
1> c:\users\jacques\documents\visual studio 2008\projects\tlib\tlib\b.h(8) : vea la declaración de 'b<T>::b'
1>c:\users\jacques\documents\visual studio 2008\projects\tlib\tlib\b.cpp(8) : error C2995: 'b<T>::~b(void)' : ya se ha definido la plantilla de función
1> c:\users\jacques\documents\visual studio 2008\projects\tlib\tlib\b.h(9) : vea la declaración de 'b<T>::~b'
In short, there are two solutions to organizing template code:
1. The "Inclusion Model" - keeping the template declarations and definitions together, as in putting them both in the same header file
2. The "Separation Model" - explicitly tell the compiler which template instantiations you're going to use by placing them in a separate compilation unit (this compilation unit needs to see both the template declarations and definitions). Both resources above show examples of this.
The problem with the second method is that you need to maintain another file with all your template instantiations. This could become a problem for large projects. However, the second solution may lead to less code bloat relative to the first method, so it could be the optimal solution in your case.
(Both resources mention using the "export" keyword though I haven't used it and it looks like there may be some compatibility issues with it. You may research this on your own if curious.)
If you're going to use the Inclusion Model and want to use two files for your template class, then it is bad practice to include a .cpp file. It's better to use a different file extension for the template implementation in this case (such as .tlt).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
//b.h
#pragma once
#ifndef B_H
#define B_H
template <class T>
class b
{
public:
b();
~b();
};
#include "b.tlt"
#endif