2014-07-24 21 views
1

我在一個庫中的cpp文件的各種模板功能,這看起來一般是這樣的:如何避免模板專門的重複打字庫許多類型/功能

template <class TT> TT im::BlockMultiplyAdd(const MtxView<TT> &src1, const MtxView<TT> &src2) 
{ 
... 
} 

,並有實例也cpp文件看起來像這樣:

template float im::BlockMultiplyAdd(const MtxView<float> &src1, const MtxView<float> &src2); 
template double im::BlockMultiplyAdd(const MtxView<double> &src1, const MtxView<double> &src2); 
template std::complex<float> im::BlockMultiplyAdd(const MtxView<std::complex<float>> &src1, const MtxView<std::complex<float>> &src2); 
template std::complex<double> im::BlockMultiplyAdd(const MtxView<std::complex<double>> &src1, const MtxView<std::complex<double>> &src2); 

我也有頭文件中的聲明。

現在我有很多這樣的功能,我生病鍵入相同的特/聲明的同組四種類型的一遍又一遍的。並不是所有的函數都有相同的參數,但它們都具有相同的四種類型,它們都是爲其構建的。

有什麼辦法,我可以做一個預處理宏或使用的模板語法或更有效地安排我的代碼,這樣我就可以減少輸入(並使其不易出錯)?

我應該把所有的代碼放在模板的頭文件中嗎?什麼是靜態庫的贊成/反對意見?

回答

1

這可能只是更容易地把它變成一個頭,而不是依靠明確的實例。但是,如果你想這樣做,你可以用TYPE這樣做

// helper.h 

// no include guard - important! 
template TYPE im::BlockMultiplyAdd(const MtxView<TYPE> &src1, const MtxView<TYPE> &src2); 
// similar stuff follows 

然後在你的CPP文件,包括其多次有不同的定義,每次:

// instantiations.cpp 

// template definition.... 

#define TYPE float 
#include "helper.h" 

#undef TYPE 
#define TYPE double 
#include "helper.h" 

#undef TYPE 
#define TYPE std::complex<float> 
#include "helper.h" 

#undef TYPE 
#define TYPE std::complex<double> 
#include "helper.h" 
//etc... 
+0

這是一個不錯的主意。 – Robotbugs

+0

其實我只是試過這個,但問題是helper.h必須包含在實現模板函數主體的相同cpp文件中,並且由於項目中有很多文件,因此需要成爲每個cpp和h文件的一個幫助文件,這是一個痛苦的工作。另外在實現中有一個單獨的文件實例化會使得難以檢查原型是否正確。 – Robotbugs

+0

其實我只是想到一個很好的直接選擇。我可以在本地'#define INST(TT)模板TT func(TT params)',然後用'INST(float)'等實例化它,然後執行'#undef INST',而不是實際複製每個實例。 – Robotbugs

0

我在做這個問題的方法最終只是創建每次出現這樣一個臨時的宏:

template <class TT> void im::BlockMultiply(MtxView<TT> dst, const MtxView<TT> &src1, const MtxView<TT> &src2) 
{ 
... 
} 

#define INST(TT) template void im::BlockMultiply(MtxView<TT> dst, const MtxView<TT> &src1, const MtxView<TT> &src2) 
INST(float); INST(double); INST(std::complex<float>); INST(std::complex<double>); 
#undef INST 

這是不是很難與切做,粘貼,因爲沒有什麼需要改變前在template之後刪除<class TT>