今天編碼的時候,發現了一個錯誤,就是模板代碼在連接的時候找不到方法。函數
狀況大概以下:this
在 "Manager.h" 中編碼
class Manager {spa
public:編譯器
template<typename T>io
void SetData(const T& value);編譯
};function
而後在cpp文件中定義SetData模板
template<typename T>class
void Manager::SetData(const T& value) {
}
在另一個main.cpp文件中使用
#include "Manager.h"
Manager mgr;
double n = 0;
mgr.SetData(n);
這樣就會產生一個error LNK2019:沒法解析的外部符號 「public: void __thiscall Manager::SetData<double>(const double&)」 xxxx,該符號在 xx函數中被引用的連接錯誤。查了一下書籍,錯誤的緣由在於,function template SetData(const T&)的定義沒有具現化,Manager.h和Manager.cpp是分開編譯的,在編譯main.cpp的過程當中,編譯器假設這個template的定義在某個地方,於是只生成一個對該定義的reference,並將這個reference所指的定義式留給連接器去決議,可是在連接期間,又找不到這樣一個定義。
Note:奇怪的是,若是n是int類型,又能夠編譯成功,可是回家後,我用本身的電腦試了一下,VS2008,int類型的也不行
解決這個問題有幾個方法:
1)採用置入式。也就是定義也放在頭文件中
2)顯示具現化一份聲明。
即在cpp文件中聲明以下 template void Manager::SetData(const double&); ,這樣作就要爲每個類型作一份聲明,比較繁瑣
3)採用export關鍵字。它會export出除inline以外的其餘方法
export template <typename T>
class Manager {
public:
void SetData(const T&); //這個聲明就會被export
void Print() {}; //不會被export
};