2011-05-16 35 views
0

可能重複:
Why can templates only be implemented in the header file?未定義的參考`無效排序::交換<int>(INT *,INT,INT)」

這是我的make文件:


#!/usr/bin/make -f 
compiler = g++ 
compiler_flags = -Wall -I /usr/include/c++/4.5 
debug_flags = -D DEBUG -g 
binary_filename = sort_testing.bin 

all: clean release 

release: 
    $(compiler) $(compiler_flags) main.cpp sort.o -o $(binary_filename) 
debug: sort.o 
    $(compiler) $(debug_flags) $(compiler_flags) main.cpp sort.o -o $(binary_filename) 
run: 
    ./$(binary_filename) 
clean: 
    rm -f *.o $(binary_filename) 
sort.o: 
    $(compiler) $(debug_flags) $(compiler_flags) -c sort.cpp 


這裏是我的C++文件:


// sort.hpp 
#ifndef SORT_H 
#define SORT_H 

namespace sort{ 
    template<class T> void swap(T*,int,int); 
} 

#endif 

// sort.cpp 
#include "sort.hpp" 

namespace sort{ 
    template<class T> 
    void swap(T* items, int index_a, int index_b){ 
     T t = items[index_a]; 
     items[index_a] = items[index_b]; 
     items[index_b] = t; 
    } 
} 

// main.cpp 
#include <iostream> 
#include <exception> 
#include <time.h> 
#include <stdlib.h> 
#include <stdio.h> 
using namespace std; 

#include "sort.hpp" 
using namespace sort; 

#define NUM_INTS 5 

int main(int argc, char** argv){ 
    try{ 
     cout << "\n\n\n"; 
     srand(time(NULL)); 
     int * int_coll = new int[NUM_INTS]; 
     for (int x = 0; x < NUM_INTS; x++) 
      int_coll[x] = rand() % 100 + 1; 
     cout << "Before swap" << endl; 
     for (int x = 0; x < NUM_INTS; x++) 
      cout << "int " << x << " == " << int_coll[x] << endl; 
     cout << "\n\n\n"; 

     cout << "Swapping ints" << endl; 
     swap<int>(int_coll, 0, 1); 

     cout << "AFter swap" << endl; 
     for (int x = 0; x < NUM_INTS; x++) 
      cout << "int " << x << " == " << int_coll[x] << endl; 
    }catch(exception& e){ 
     cout << "Exception: " << e.what() << endl; 
    } 
    return 0; 
} 

而且,這裏是我的問題:

./make clean debug 
rm -f *.o sort_testing.bin 
g++ -D DEBUG -g -Wall -I /usr/include/c++/4.5 -c sort.cpp 
g++ -D DEBUG -g -Wall -I /usr/include/c++/4.5 main.cpp sort.o -o sort_testing.bin 
/tmp/ccRl2ZvH.o: In function `main': 
/home/dev/c++/sorting/main.cpp:33: undefined reference to `void sort::swap<int>;(int*, int, int)' 
collect2: ld returned 1 exit status 
make: *** [debug] Error 1 

不知道如何解決這個問題?

+0

你不需要'swap '。該類型可以從'int_coll'推導出來。 – Xeo 2011-05-16 06:10:47

回答

0

模板定義必須在同一個文件中。所以在頭文件本身中定義函數。

或者包括.cpp文件中的頭底部爲:

// sort.hpp 
#ifndef SORT_H 
#define SORT_H 

namespace sort{ 
    template<class T> void swap(T*,int,int); 
} 


#include "sort.cpp" //<--------------- this! 

#endif 
+0

如果你這樣做,通常重新命名sort.cpp是很有用的,這樣構建工具不會不小心嘗試構建它。 – 2011-05-16 06:26:57

1

模板定義,需要在使用(這樣他們可以隱式實例化)OR你需要明確實例化它們的點要麼是可見的(在這種情況下,鏈接將帶來顯式實例和程序一起使用) 。

在你的情況下,我會選擇一個(和隱式實例化)。這意味着你需要的模板定義(的模板)移到頭文件:

// sort.hpp 
#ifndef SORT_H 
#define SORT_H 

namespace sort{ 
    template<class T> 
    void swap(T*,int,int) 
    { 
     T t = items[index_a]; 
     items[index_a] = items[index_b]; 
     items[index_b] = t; 
    } 
} 

#endif 

或者(但在一般情況下不太有用(但有它的用途))是顯式模板實例化。在這裏你可以在sort.cpp中定義你想要定義的模板的變體。

// sort.cpp 
#include "sort.hpp" 

namespace sort{ 
    template<class T> 
     void swap(T* items, int index_a, int index_b){ 
      T t = items[index_a]; 
      items[index_a] = items[index_b]; 
      items[index_b] = t; 
     } 

    // Define an explicit function template instantiation. 
    // Here we define that the integer version of the template must exist. 
    template void swap<int>(int*,int,int); 
} 

當您想要限制可用模板版本的數量時,這非常有用。

+0

+ 1用於顯示源文件中的*顯式函數模板實例*。我沒有想到這一點。 – Nawaz 2011-05-16 07:05:38

相關問題