2012-10-11 49 views
1

可能重复:
C++ template, linking error解析的外部符号 - 模板类

我试图实现一个选择排序,但我不断收到错误(印刷在其下方)。在我看来,我所有的包含和模板都是正确的。有人可以向我解释此错误的原因以及调试此类错误的一般方法。它通常在包含或模板问题时似乎发生,但偶尔会发生在我不知道哪里出错的情况下。谢谢。

错误LNK2019:无法解析的外部符号 “市民:无效__thiscall选择::选择排序为(int * const的,INT)” 函数引用(?选择排序@ $选择3 H @@ QAEXQAHH @ Z)_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; 
} 
+0

@DavidRodríguez-dribeas只是做了 – PiotrNycz

回答

5

SelectionSort.cpp的内容移至SelectionSort.h,位于类声明的下方。同时确保你在整个.h文件的内容周围都有一个头文件。

问题来自C++如何实现模板。每次看到与模板类一起使用的新类型(如Selection<int>)时,它将重新创建整个班级,用int替换ItemType

因此,它需要在编译时知道该类的全部定义(及其方法)。它不能直接使用类定义和延迟链接。

+0

感谢您的回应。我之前使用过模板,同时将我的代码分离到声明和实现文件中。当我回顾这些项目时,我找不到任何区别。你知道以前的项目可能会编译什么吗? – Zzz

+0

我只记得我做了什么让他们编译。我添加了包含防护,并在测试驱动中包含了.cpp实现文件。这是如何改变编译来使所有的工作? – Zzz

+0

@Azzi,底线是编译器需要能够在编译'test.cpp'文件时看到模板类的整个实现。包括CPP文件是可行的,因为编译器可以访问完整的实现细节,但是我总是发现它比它的价值更令人困惑。 – riwalk