這裡實現乙個通用的計算陣列類的資料求和函式。c++中用模板實現多型屬於靜態多型,trait類就是做為模板引數以實現靜態多型。根據不同的模板引數型別,以實現不同模板資料型別所需的功能。其實說白了,就是利用模板的一些基本規則,將其合理的組合起來,以達到根據型別不同時函式的操作有細微個性的差別。
依據tdd開發模式,先寫測試用例。
#include #include #include "accum.hpp"
using namespace std;
int main(int argc, char **argv)
; cout << accum(arr, arr+5) << endl;
assert(accum(arr, arr+5) == 15);
return 0;
}
1、沒有使用trait的實現方式
template inline t& accum(t const* beg, t const* end)
return total;
}
上述**的缺點:1、初始化不一定是初始值為0;2、t型別求和可能導致型別溢位。
2、解決型別溢位問題,採用型別關聯方式實現
//通過特化形式,將型別關聯起來,以擴大型別的範圍
templatestruct accumulatetraits; //trait模板
template<> //模板特化,型別關聯
struct accumulatetraits;
template<>
struct accumulatetraits;
template<>
struct accumulatetraits;
template<>
struct accumulatetraits;
template<>
struct accumulatetraits;
#include "traits.hpp"
templateinline typename accumulatetraits::acct accum(t const* beg, t const* end)
return total;
}
3、在2的基礎上解決初始化不為0問題(value trait——值萃取)
templatestruct accumulatetraits; //trait模板
template<> //模板特化,型別關聯
struct accumulatetraits
};template<>
struct accumulatetraits
};template<>
struct accumulatetraits
};template<>
struct accumulatetraits
};template<>
struct accumulatetraits
};
#include "traits.hpp"
templateinline typename accumulatetraits::acct accum(t const* beg, t const* end)
return total;
}
上述**的缺點是:型別繫結過死板,已經繫結不能被修改,有時也需要對型別進行自行定製。
4、採用引數化的形式進行型別萃取(trait)
template>
struct accum
return total;
}};
//test case
#include #include #include "accum.hpp"
using namespace std;
int main(int argc, char **argv)
; assert(accum::accum(arr, arr+5) == 15);
return 0;
}
總之,型別萃取(trait)在處理型別關聯有大的作用。 C 型別萃取
在c 中我們可以通過typeid來獲取乙個型別的名稱 內建型別和自定義型別都可以 但是我們不能用這種方式獲取來的名稱做變數的宣告。那麼在c 中怎樣識別物件的型別呢?我們可以通過型別萃取的方式來區分內建型別和自定義型別。例如 我們在seqlist中要用到型別萃取,因為內建型別我們可以通過memcopy...
C 型別萃取
當我們遇到這樣的場景時,我們會用到型別萃取 template void copy t dst,t str,size t n 模板函式copy void test string s2 10 int l1 10 int l2 10 copy s1,s2,10 copy l1,l2,10 for size...
C 型別萃取
型別萃取依靠的就是模版的特化,模版的特化又分為全特化和偏特化,根據不同的情況做相應的呼叫。函式模版特化 函式模版只有全特化,而沒有偏特化。沒有偏特化的原因是已經有了函式過載。通用模版並不總是正確的,在某些情況下有可能是錯誤的。例如 include using namespace std templa...