4

Possible Duplicate:
C++ template, linking error

I am attempting to implement a selection sort, but I keep getting the error(printed below). It seems to me that all my includes and templates are done correctly. Can someone explain to me the reason for this error and the general approach to debugging this type of error. It usually seems to happen when there is an include or template issues, but occasionally it occurs in situation where I have no idea what is wrong. Thanks.

error LNK2019: unresolved external symbol "public: void __thiscall Selection::SelectionSort(int * const,int)" (?SelectionSort@?$Selection@H@@QAEXQAHH@Z) referenced in function _main

test.cpp

#include <iostream>
#include "SelectionSort.h"
using namespace std;

void main()
{
    int ar[] = {1,2,3,4,5};
    Selection<int> s;
    s.SelectionSort(ar,5);

    for(int i = 0; i < 5; i++)
    {

        cout << "\nstudent number " << i + 1<< " grade " << ar[i];
    }
}

SelcectionSort.h

template<class ItemType>
class Selection
{
public:
    void SelectionSort(ItemType[], int);
private:
    int MinIndex(ItemType[], int, int);
    void Swap(ItemType& , ItemType&);
};

SelectionSort.cpp

#include "SelectionSort.h"

template<class ItemType>
void Selection<ItemType>::SelectionSort(ItemType values[], int numValues)
// Post: The elements in the array values are sorted by key.
{
int endIndex = numValues-1;
for (int current = 0; current < endIndex; current++)
Swap(values[current],
values[MinIndex(values, current, endIndex)]);
}

template<class ItemType>
int Selection<ItemType>::MinIndex(ItemType values[], int startIndex, int endIndex)
// Post: Returns the index of the smallest value in
// values[startIndex]..values[endIndex].
{
int indexOfMin = startIndex;
for (int index = startIndex + 1; index <= endIndex; index++)
if (values[index] < values[indexOfMin])
indexOfMin = index;
return indexOfMin;
}

template<class ItemType>
inline void Selection<ItemType>::Swap(ItemType& item1, ItemType& item2)
// Post: Contents of item1 and item2 have been swapped.
{
ItemType tempItem;
tempItem = item1;
item1 = item2;
item2 = tempItem;
}
Community
  • 1
  • 1
Zzz
  • 2,927
  • 5
  • 36
  • 58

1 Answers1

8

Move the contents of SelectionSort.cpp to SelectionSort.h, just below the class declaration. Also ensure that you have a header guard around the contents of your entire .h file.

The problem comes from how C++ implements templates. Every time it sees a new type used with a template class (like Selection<int>), it recreates the entire class, replacing ItemType with int.

For this reason, it needs to know the full definition of the class (along with its methods) at compile time. It cannot just use the class definition and delay linking until later.

riwalk
  • 14,033
  • 6
  • 51
  • 68
  • Thanks for the response. I have used templates before while separating my code into a declaration and implementation file. When I look back to those projects I can't find a difference. Do you know what might have made the previous project compile? – Zzz Oct 12 '12 at 00:38
  • I just remembered what I did to get them to compile. I added include guards and also included the .cpp implementation file in the test driver. How does that change compilation to make everything work? – Zzz Oct 12 '12 at 00:52
  • @Azzi, the bottom line is that the compiler needs to be able to see the entire implementation of your template class while compiling the `test.cpp` file. Including the CPP file works because the compiler then gets access to the full implemention details, but I've always found that to be more confusing than it is worth. – riwalk Oct 12 '12 at 14:12