Automatically converts N-layer collection objects to corresponding. Net generic objects (C ++)

Source: Internet
Author: User
Tags traits

When someone encountered a problem yesterday, I came back at night and thought about a solution to type deduction using templates.

The problem itself needs to be clear, that is, you need to write an util function to automatically convert the template set objects in C ++.. Net (for example, convert vector <int> to list <int> ^. Because the type is not fixed, it is the best choice to use a template for conversion. The difficulty is that these collection classes can also be nested types, that is to say, the set is still installed in the Set (for example, converting the vector <int> to list <int> ^), and even the nested multi-layer set needs to be considered.

  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, role <internalnativetype >:: iscollection (), role <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 <int >=> 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 <int>, 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 <string >=> 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 <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. }

The code above will not be explained much. For more information about type traits, see this article. For more information about specialization and partial specialization, see Mr Hou Jie's STL source code analysis. In particular, though. net generic principle does not support the use of special and biased (because. net generic is the runtime mechanism, considering. net strong meta data, I personally think it is not necessary), but the C ++/CLI can still use templates for special/partial special processing. For example, the managed_type_traits <t ^> type in the above code is used to extract the original type without the ^ symbol, so that the template can automatically generate gcnew T (...) this is the code. The anyway and C ++ templates are the same as those of macro (macro), depending on how you use them to generate the required code.

I remember reading a lot of special and special templates when I learned C ++ N years ago. When I read the source code of libraries such as STL and boost, I also found that the template metadata programming (TMP) the idea is fully realized. But I am ashamed that I haven't used coding before. I tried it myself this time, the function is still very powerful (please do not compare it with dynamic languages such as Ruby, after all they are totally different ).

 

Conclusion: Playing TMP is actually a battle with the compiler. It's fun :)

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.