2013-04-30 85 views
4

我想編寫一個玩具程序來運行C++,但是我得到了一個奇怪的未定義的引用錯誤,我無法解決。編譯多個文件時出現奇怪的未定義引用錯誤

我的代碼由3個文件:

ex13_6.h:

#include<vector> 

namespace ex13_6 { 
    template<class T> class Cmp { 
    public: 
     static int eq(T a, T b) {return a == b;} 
     static int lt(T a, T b) {return a < b;} 
    }; 

    template<class T, class C = Cmp<T> > void bubble_sort(std::vector<T> &v); 
} 

ex13_6.cpp

#include<vector> 
#include"ex13_6.h" 

namespace ex13_6 { 
    template<class T, class C = Cmp<T> > void bubble_sort(std::vector<T> &v) { 
     int s = v.size(); 
     T swap; 
     for (int i=0; i<s; i++) { 
      for (int j=0; j<s; j++) { 
       if (C::lt(v.at(j), v.at(i))) { 
        swap = v.at(i); 
        v.at(i) = v.at(j); 
        v.at(j) = swap; 
       } 
      } 
     } 
    } 
} 

main.cpp中:

#include"ex13_6.h" 
#include<iostream> 
#include<vector> 

using namespace std; 
using namespace ex13_6; 

int main() { 
    // Sort using default comparison for int 
    vector<int> v_int; 
    for (int i=0; i<10; i++) { 
     v_int.push_back(10-i); 
    } 
    bubble_sort(v_int); 
    cout << "sort of int vector:\n"; 
    for (vector<int>::const_iterator it = v_int.begin(); it != v_int.end(); it++) { 
     cout << ' ' << *it; 
    } 
    cout << '\n'; 
} 

而且我編譯使用:

g++ main.cpp -o main -std=gnu++0x ex13_6.cpp 

以下是錯誤消息:

/tmp/ccRwO7Mf.o: In function `main': 
main.cpp:(.text+0x5a): undefined reference to `void ex13_6::bubble_sort<int, ex13_6::Cmp<int> >(std::vector<int, std::allocator<int> >&)' 
collect2: ld returned 1 exit status 

我真的很感激任何幫助!

+4

您可能需要在'ex13_6.cpp'中顯式模板實例,或者您應該將模板函數的實現移動到頭文件'ex13_6.h'中。請參閱:http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file – jxh 2013-04-30 20:16:16

+0

謝謝@ user315052。但爲什麼我不能將通用模板函數定義放在ex13_6.cpp中? – user690421 2013-04-30 20:18:27

+0

@ user690421:你可以,但你需要一個明確的實例,正如我所解釋的。看到引用SO問題。 – jxh 2013-04-30 20:19:45

回答

3

移動你的bubble_sort模板的實施到你的頭文件。

模板不像Java的泛型,所有的奇蹟都發生在C++的編譯時。爲了使編譯器爲每個模板實例化生成代碼,它必須是可見的,爲此,它必須位於標題(或其他文件)中,並且包含在使用它的每個翻譯單元中。

1

你的模板函數的定義應該是在ex13_6.h文件:

#include<vector> 

namespace ex13_6 { 
    template<class T> class Cmp { 
    public: 
     static int eq(T a, T b) {return a == b;} 
     static int lt(T a, T b) {return a < b;} 
    }; 

    template<class T, class C = Cmp<T> > void bubble_sort(std::vector<T> &v) { 
     int s = v.size(); 
     T swap; 
     for (int i=0; i<s; i++) { 
      for (int j=0; j<s; j++) { 
       if (C::lt(v.at(j), v.at(i))) { 
        swap = v.at(i); 
        v.at(i) = v.at(j); 
        v.at(j) = swap; 
       } 
      } 
     } 
    } 
} 
0

您需要將模板實現放在頭文件中。

當實例化一個模板時,編譯器需要「看」實現,所以如果你只包含頭部,實現需要在那裏。

請勿包含.cpp文件。

相關問題