Compiling and Linking with Templates

 

 

There is an interesting fact that many compilers when you have separate header and cpp files for your definition of a class (AS IS the proper OOP coding sytle) using templates will not put uninstantiated template definitions (specifically the member function) into object (.OBJ) files. This means the linker will look for them failing and giving a linking error.

 

This code can cause a linker problem ....of not finding the setArray member function.

 

SSortedList.h file

template <class T> class SSortedList
{
public:

    void setArray(int setSize);

private:
    T searchElement;
    T *array_ptr;
    int size;
};

SSortedList.cpp file#include <iostream>

#include <string>

#include <stdlib.h>

#include "SSortedList.h"

using namespace std;

template <class T>
void SSortedList<T>::setArray(int setSize)
{
     size = setSize;
     array_ptr = new T[setSize];
}

 

 

Solution 1: Put explicit instantiation declarations for each type you are going to use in your .cpp file.

Fix the problem by forcing the placement into the obj file

 

SSortedList.h file

template <class T> class SSortedList
{
public:

    void setArray(int setSize);

private:
    T searchElement;
    T *array_ptr;
    int size;
};

SSortedList.cpp file#include <iostream>

#include <string>

#include <stdlib.h>

#include "SSortedList.h"

using namespace std;

template <class T>
void SSortedList<T>::setArray(int setSize)
{
     size = setSize;
     array_ptr = new T[setSize];
}

//explicit instantiation
template class SSortedList<int>;
template class SSortedList<string>;

 

 

 

 

Solution 2: Put all of your code inside the .h file (not normal proceedure) and then you do not have to instantiate will put code in .obj file.

Fix the problem

SSortedList.h file

template <class T> class SSortedList
{
public:

    void setArray(int setSize);

private:
    T searchElement;
    T *array_ptr;
    int size;
};

 

template <class T>
void SSortedList<T>::setArray(int setSize)
{
     size = setSize;
     array_ptr = new T[setSize];
}

 

 

© Lynne Grewe