將N層集合對象自動轉化為對應的.NET泛型對象(C++)

來源:互聯網
上載者:User

昨天別人碰到的問題,晚上回來想了一下給出了一個用模板進行類型推導的解決方案。

問題本身需求很清楚,就是需要寫一個Util函數,將C++裡面的那些模板(template)集合對象自動轉換成.NET裡面的泛型(Generic)集合對象,比如將vector<int>轉化成List<int>^。因為類型(Type)不定,所以用模板來進行轉化是不二的選擇。問題的痛點在於這些集合類還可以是巢狀型別,也就是說集合裡面裝的還是集合(比如將vector<vector<int> >轉化成List<List<int>^>^),甚至還得考慮多層集合嵌套的情況。

  1. // NativeToManagedTypeApp.cpp : main project file.
  2. // author: Anders Deng
  3. // date: 2008/8/29
  4. #include "stdafx.h"
  5. #include <vector>
  6. using namespace System;
  7. using namespace System::Collections::Generic;
  8. using namespace std;
  9. // for method overload 
  10. struct __true__value {};
  11. struct __false__value{};
  12. // some classes for type traits
  13. template<class T>
  14. struct collection_Type_Traits
  15. {
  16.     typedef __false__value isCollection;
  17.     typedef T __template__param__type;
  18. };
  19. template<typename T>
  20. struct collection_Type_Traits<std::vector<T> >
  21. {
  22.     typedef __true__value isCollection;
  23.     typedef T __template__param__type;
  24. };
  25. template<class T>
  26. struct collection_Type_Traits<List<T>^ >
  27. {
  28.     typedef __true__value isCollection;
  29.     typedef T __template__param__type;
  30. };
  31. // add more specialization template definition
  32. // ... 
  33. template<class T>
  34. struct managed_Type_Traits
  35. {
  36.     typedef __false__value isValueType;
  37.     typedef T param_type_name;
  38. };
  39. template<class T>
  40. struct managed_Type_Traits<T^>
  41. {
  42.     typedef __false__value isValueType;
  43.     typedef T param_type_name; // remove ^ from reference type
  44. };
  45. template<>
  46. struct managed_Type_Traits<int>
  47. {
  48.     typedef __true__value isValueType;
  49.     typedef int param_type_name;
  50. };
  51. // add more specialization template definition for other required value class
  52. // ...
  53. public ref class Util
  54. {
  55. public:
  56.     template<class NativeType, class ManagedType>
  57.     static ManagedType nativeToManaged(NativeType nativeObj)
  58.     {
  59.         return __nativeToManaged<NativeType, ManagedType>(nativeObj, collection_Type_Traits<NativeType>::isCollection(), managed_Type_Traits<ManagedType>::isValueType());
  60.     }
  61. private:
  62.     // collection && reference type
  63.     template<class NativeType, class ManagedType>
  64.     static ManagedType __nativeToManaged(NativeType nativeObj, __true__value, __false__value)
  65.     {
  66.         ManagedType list = gcnew managed_Type_Traits<ManagedType>::param_type_name();
  67.         for (NativeType::iterator it = nativeObj.begin(); it != nativeObj.end(); ++it)
  68.         {
  69.             typedef collection_Type_Traits<NativeType>::__template__param__type InternalNativeType;
  70.             typedef collection_Type_Traits<ManagedType>::__template__param__type InternalManagedType;
  71.             list->Add(__nativeToManaged<InternalNativeType, InternalManagedType>(*it, collection_Type_Traits<InternalNativeType>::isCollection(), managed_Type_Traits<InternalManagedType>::isValueType()));
  72.         }
  73.         return list;
  74.     }
  75.     // non-collection && reference type
  76.     template<class NativeType, class ManagedType>
  77.     static ManagedType __nativeToManaged(NativeType nativeObj, __false__value, __false__value)
  78.     {
  79.         return gcnew managed_Type_Traits<ManagedType>::param_type_name(nativeObj.c_str());
  80.     }
  81.     // non-collection && reference type
  82.     template<class NativeType, class ManagedType>
  83.     static ManagedType __nativeToManaged(NativeType nativeObj, __false__value, __true__value)
  84.     {
  85.         return nativeObj;
  86.     }
  87. };
  88. int main(array<System::String ^> ^args)
  89. {
  90.     // ----------------------------------
  91.     // test vector<int> => List<int>^
  92.     // ----------------------------------
  93.     vector<int> intV;
  94.     intV.push_back(4);
  95.     intV.push_back(5);
  96.     List<int>^ l = Util::nativeToManaged<vector<int>, List<int>^>(intV);
  97.     for each(int i in l)
  98.     {
  99.         Console::Write("{0} ", i);
  100.     }
  101.     Console::WriteLine();
  102.     // ----------------------------------
  103.     // test vector<vector<int>> => List<List<int>^>^
  104.     // ----------------------------------
  105.     vector<vector<int>> iVV;
  106.     vector<int> iV;
  107.     iV.push_back(1);
  108.     iV.push_back(2);
  109.     iVV.push_back(iV);
  110.     List<List<int>^ >^ list = Util::nativeToManaged<vector<vector<int> >, List<List<int>^>^ >(iVV);
  111.     for each(List<int>^ l in list)
  112.     {
  113.         for each(int i in l)
  114.             Console::Write("{0} ", i);
  115.         Console::WriteLine();
  116.     }
  117.     // ---------------------------------
  118.     // test vector<vector<string>> => List<List<String^>^>^
  119.     // ---------------------------------
  120.     vector<string> sV;
  121.     vector<vector<string>> sVV;
  122.     sV.push_back("abc");
  123.     sV.push_back("def");
  124.     sV.push_back("ghi");
  125.     sVV.push_back(sV);
  126.     List<List<String^>^>^ sll = Util::nativeToManaged<vector<vector<std::string>>, List<List<String^>^>^>(sVV);
  127.     for each(List<String^>^ sl in sll)
  128.     {
  129.         for each(String^ s in sl)
  130.             Console::Write("{0} ", s);
  131.         Console::WriteLine();
  132.     }
  133.     return 0;
  134. }

代碼如上,就不多解釋了。關於type traits可以參考這篇文章,關於特化(specialization)、偏特化(partial specialization)的文章可以看侯捷先生的《STL源碼分析》。需要特別指出的是,雖然.NET的Generic原理上不支援特化和偏特化的用法(因為.NET泛型是運行時機制,考慮到.NET極強的meta data,個人覺得確實也不必要),但是C++/CLI使用的時候仍然可以利用模板來進行特化/偏特化處理。比如上面代碼中的managed_Type_Traits<T^>類型就是用來提取不帶^符號的原始類型,這樣就可以讓模板自動產生出gcnew T(...)這樣的代碼了。Anyway,C++的模板就跟宏(Macro)一樣,就看你怎麼運用其產生需要的代碼了。

記得n年前學C++的時候看過不少講模板特化,偏特化的資料,讀STL、boost等Library原始碼的時候也發現裡面將模板元編程(TMP)的思想發揮的淋漓盡致。不過慚愧的是自己真正coding的時候還沒直接用過,這次算是親自試了一把,功能還是很強大的(當然請不要拿來與諸如Ruby這樣的動態語言比,畢竟they are totally different)。

 

小結:玩TMP實際上就是與編譯器鬥,其樂無窮:)

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.