2012-06-19 61 views
0

我有以下簡單的模板代碼:模板 - 未定義的引用錯誤

#ifndef CLUSTER_H 
#define CLUSTER_H 

#include <iostream> 
#include <vector> 

template <typename T, size_t K> 
class Cluster 
{ 
public: 
    void Print() const;  
private: 
    std::vector<T> objects; 
}; 
template <typename T, size_t K> 
void Cluster<T,K>::Print() const 
{ 
    for (int i=0; i<objects.size(); i++) 
    { 
     T curr=objects[i]; 
     std::cout << curr << " "; 
    } 
    std::cout << std::endl; 
} 

#endif 

出於某種原因,我得到以下錯誤:「未定義的引用‘Cluster<int, 5u>::Print() const’可能是什麼造成這種情況的原因 ?謝謝!

+0

你能提供一些代碼來產生錯誤,例如:致集羣 ::打印? – Rook

+1

http://ideone.com/cMTih適合我。 – Griwes

+0

分享你的** main()**以及如何編譯你的程序。使用模板始終提供完整的錯誤消息。 – tuxuday

回答

1

因此,我打算在這裏說一說,你已經在CPP文件中定義了一個模板函數,這意味着它將以不同的翻譯單位結束。下面是一個簡單的例子:

的報頭,example.h文件

#ifndef EXAMPLE_H 
#define EXAMPLE_H 

template<int TValue> 
class example 
{ 
public: 
    int get_tvalue(); 
}; 

#endif 

源文件,example.cpp

#include "example.h" 

template<int TValue> 
int example<TValue>::get_tvalue() 
{ 
    return TValue; 
} 

而另一個源文件,main.cpp中

#include "example.h" 

int main() 
{ 
    example<5> instance; 
    instance.get_tvalue(); 
    return 0; 
} 

如果我編譯這些一起使用GCC,我得到undefined reference to 'example<5>::get_tvalue()'。這是因爲模板類被實例化的方式。模板類的定義就是......模板,而不是實際的類。實際的類定義是在該類的參數化(或特別是完全專用)定義發生時創建的,在這種情況下爲example<5>。完全專用的類定義只存在於main.cpp中... example.cpp中沒有這樣的類! Example.cpp僅包含模板,並沒有專門化。這意味着函數get_tvalue沒有爲main.cpp中的example<5>定義,因此是錯誤。

您可以通過以下兩種方法之一來解決此問題。第一種方法是始終將您的整個模板類定義在其頭文件中。例如,這是用STL容器完成的方式。另一種方法是強制example.cpp參數化類的創作......您可以通過添加

template class example<5>; 

到example.cpp結束做到這一點。因爲在example.cpp中現在有一個example<5>的實際類定義,所以您還將獲得example<5>::get_tvalue的實際函數定義,並且在編譯步驟結束時將翻譯單元main.o和example.o鏈接在一起時,一切都會好起來的。

顯然,在大多數情況下,這將是一個糟糕的做法,但在模板參數只採用一小範圍的值的情況下,它可以工作。把你的整個類放在頭文件中可能是最簡單,最安全和最靈活的。