2012-12-22 55 views
1

Possible Duplicate:
C++ templates, undefined reference未定義參照

我有一個非常簡單的程序包括三個文件,它們從普通陣列構建載體:

//create.hpp 

#ifndef CREATE_HPP_ 
#define CREATE_HPP_ 

#include <vector> 

using namespace std; 

template<class T> 
vector<T> create_list(T uarray[], size_t size); 

#endif /* CREATE_HPP_ */ 

//create.cpp 

#include "create.hpp" 

template<class T> 
vector<T> create_list(T uarray[], size_t size){ 
    vector<T> ulist(uarray, uarray + size); 
    return ulist; 
} 

//main.cpp 

#include <vector> 
#include <iostream> 

#include "create.hpp" 

using namespace std; 


int main(){ 
    char temp[] = { '/', '>' }; 
    vector<char> uvec = create_list<char>(temp, 2); 

    vector<char>::iterator iter=uvec.begin(); 
    for(;iter != uvec.end();iter++){ 
     cout<<*iter<<endl; 
    } 

    return 0; 
} 

構建過程如下:

g++ -O0 -g3 -Wall -c -fmessage-length=0 -o create.o create.cpp 
g++ -O0 -g3 -Wall -c -fmessage-length=0 -o main.o main.cpp 
g++ -o main.exe main.o create.o 

在構建程序,我得到這個錯誤:

main.o: In function `main': 
../main.cpp:18: undefined reference to `std::vector<char, std::allocator<char> > create_list<char>(char*, unsigned int)' 

這個程序是非常簡單的。但是,編譯成功,但鏈接失敗。然後我將所有的代碼移動到一個文件中,一切都像魅力一樣。有人能幫我弄清楚這個嗎?

+1

.cpp中的模板定義?答案_nine億次_。請搜索。 –

+0

是的,我搜索並找到了幾個答案,但這些答案並沒有幫助我理解這個問題。 – RainSia

回答

6

是的。答案很複雜。它與模板在C++中的工作方式有關。

簡答題:完整的模板定義必須位於頭文件中,或者您必須爲CPP文件中的給定類型顯式實例化(例如http://msdn.microsoft.com/en-us/library/by56e477(v=vs.80).aspx)。

長答案(原因):模板不是可以編譯成二進制(對象)的代碼。它們僅僅是「創建代碼的祕訣」,代碼只能在實例化過程中創建。這也是爲什麼模板的不準確使用可能會導致編譯時間過長並且比所需的二進制文件更大。

+1

+1這個顯而易見的重複,因爲這是我在這個問題上看到了很長時間的最明確的答案之一。 –

+0

+1。 @RainSia,如果不清楚的話,一個解決辦法是將所有的代碼從create.cpp移到create.h中(另一種方法是明確的實例化)。 – jimhark

+1

我喜歡這個答案。這很清楚,我完全理解這個問題的根本原因。非常感謝你。 – RainSia

3

您已經在單獨的.cpp文件中定義了您的模板。每個文件都是分開編譯的。您的create.cpp不包含任何正在運行的代碼,因此它將被編譯器丟棄。之後,在鏈接階段,當鏈接器嘗試鏈接main.cppcreate_list的二進制文件時,它無法在其他編譯對象中找到它,因此您收到此錯誤。要解決它,你需要在你的create.cpp中至少一次實例化你的模板,或者在頭文件中有實現。