C++特化的应用——类型萃取
生活随笔
收集整理的這篇文章主要介紹了
C++特化的应用——类型萃取
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
-
提出問題:如何實現一個對于拷貝內置類型和自定義類型通用的拷貝函數?
1、拷貝內置類型
對于內置類型我們可以用memcpy進行拷貝,因為memcpy屬于淺拷貝,內置類型不涉及資源管理的問題。
2、拷貝自定義類型
拷貝自定義類型時有可能會涉及到深拷貝(如string)涉及到了資源管理,就不能使用memcpy。
所以給出了一種方法:賦值
void Copy(T* dst, const T* src, size_t size) {for (size_t i = 0; i < size; ++i) { dst[i] = src[i]; } }int main() {std::string strarr1[3] = { "11", "22", "33" }; std::string strarr2[3]; Copy(strarr2, strarr1, 3);return 0; }我們使用循環賦值的方式來進行拷貝,但發現這樣做效率很低。
?
- 那能否將上述兩種方法結合起來,遇到內置類型就用memcpy來拷貝,遇到自定義類型就用賦值方式來做呢?
?
改進一? 我們增加一個bool類型區分 內置類型 與 自定義類型 。
true就是內置類型,false就是自定義類型。?
void Copy(T* dst, const T* src, size_t size, bool IsPODType) {if(IsPODType)memcpy(dst, src, sizeof(T)*size);else{for (size_t i = 0; i < size; ++i){dst[i] = src[i];}} }但發現這樣做,用戶就需要手動的添加最后一個參數,易出錯。
那能否讓一個函數自動去識別所拷貝類型是內置類型或者自定義類型呢?
改進二??使用函數區分內置于自定義類型
bool IsPODType(const char* strType) {// 此處只是舉例,只列出個別類型 const char *arrType[] = { "char", "short", "int", "long", "long long", "float", "double", "long double" }; for (auto e : arrType){if (strcmp(e, strType) == 0)return true;}return false; }template<class T> void Copy(T* dst, const T* src, size_t size) {if(IsPODType(typeid(T).name()) //typeid來確認所拷貝對象的實際類型memcpy(dst, src, sizeof(T)*size);else{for (size_t i = 0; i < size; ++i){dst[i] = src[i];}} }但這樣做需要將所有的類型遍歷一遍,且每次比較都是字符串的比較,效率較低。
改進三? 類型萃取
為了將內置類型與自定義類型區分開,給出以下兩個類分別代表內置類型與自定義類型。
//代表內置類型 struct TrueType {static bool Get(){return true;} }; //代表自定義類型 struct FalseType {static bool Get(){return false;} };再給出類模板,用戶可以按照任意類型實例化該模板
通過將基本類型每個都特化一次,在識別時就可以直接確定出所傳入的參數的類型。
在對基本類型特化時,必需要將所有的類型都特化一變,包括有符號和無符號的類型。這里只給出了幾種。
//給出模板 template<class T> struct TypeTraits { typedef FalseType IsPODType; };//對上述的類模板進行以下方式的實例化 template<> struct TypeTraits<char> { typedef TrueType IsPODType; }; template<> struct TypeTraits<short> { typedef TrueType IsPODType; }; template<> struct TypeTraits<int> { typedef TrueType IsPODType; }; template<> struct TypeTraits<long> { typedef TrueType IsPODType; };?
類型萃取總代碼:
#include <iostream> #include <string>//代表內置類型 struct TrueType {static bool Get(){return true;} }; //代表自定義類型 struct FalseType {static bool Get(){return false;} };//給出模板 template<class T> struct TypeTraits { typedef FalseType IsPODType; }; //對上述的類模板進行以下方式的實例化 template<> struct TypeTraits<char> { typedef TrueType IsPODType; }; template<> struct TypeTraits<short> { typedef TrueType IsPODType; }; template<> struct TypeTraits<int> { typedef TrueType IsPODType; }; template<> struct TypeTraits<long> { typedef TrueType IsPODType; };template<class T> void Copy(T* dst, const T* src, size_t size) {//通過對TypeTraits類模板,來確認所拷貝對象的實際類型if(TypeTraits<T>::IsPODType::Get())memcpy(dst, src, sizeof(T)*size);else{for (size_t i = 0; i < size; ++i){dst[i] = src[i];}} }int main() {int a1[] = { 1,2,3,4,5,6,7,8,9,0 }; int a2[10]; Copy(a2, a1, 10); //內置類型調用特化 intstd::string strarr1[3] = { "11", "22", "33" }; std::string strarr2[3]; Copy(strarr2, strarr1, 3); //自定義類型調用模板return 0; }?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的C++特化的应用——类型萃取的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++ 模板特化
- 下一篇: Linux——进程间通信(总结)