fork download
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. using namespace std;
  5.  
  6. int value = 'A';
  7.  
  8. // static assert helper
  9. template <bool b>
  10. struct StaticAssert {};
  11.  
  12. template <>
  13. struct StaticAssert<true>
  14. {
  15. static void test(const string& s) {}
  16. };
  17.  
  18.  
  19. // helper struct that saves us from partially specialized method overloads
  20. template < class RequestedType, class ActualType, class TContentHolder >
  21. struct Getter;
  22.  
  23.  
  24. // holds a vector of type TContent, recursively inherits from holders of other types
  25. template < class TContent, class TAddContentHolders >
  26. class ContentHolder : public ContentHolder< typename TAddContentHolders::ContentType, typename TAddContentHolders::AdditionalContentTypes >
  27. {
  28. public:
  29. typedef TContent ContentType;
  30. typedef TAddContentHolders AdditionalContentTypes;
  31.  
  32. private:
  33. typedef ContentHolder< typename TAddContentHolders::ContentType, typename TAddContentHolders::AdditionalContentTypes > ParentType;
  34.  
  35. public:
  36. vector< ContentType > mVector;
  37.  
  38. ContentHolder()
  39. {
  40. for ( int i = 0; i < 5; ++i )
  41. {
  42. mVector.push_back( ContentType(value++) );
  43. }
  44. }
  45.  
  46. virtual ~ContentHolder() {}
  47.  
  48. template < class RequestedType >
  49. RequestedType get()
  50. {
  51. return Getter< RequestedType, ContentType, ContentHolder < TContent, TAddContentHolders > >::get(this);
  52. }
  53. };
  54.  
  55. // specialization for ending the recursion
  56. template < class TContent >
  57. class ContentHolder< TContent, bool >
  58. {
  59. public:
  60. typedef TContent ContentType;
  61. typedef bool AdditionalContentTypes;
  62.  
  63. vector< ContentType > mVector;
  64.  
  65. ContentHolder()
  66. {
  67. for ( int i = 0; i < 5; ++i )
  68. {
  69. mVector.push_back( ContentType(value++) );
  70. }
  71. }
  72.  
  73. virtual ~ContentHolder() {}
  74.  
  75. template < class RequestedType >
  76. RequestedType get()
  77. {
  78. return Getter< RequestedType, ContentType, ContentHolder< ContentType, bool > >::get(this);
  79. }
  80. };
  81.  
  82.  
  83. // default getter: forwards call to parent type
  84. template < class RequestedType, class ActualType, class TContentHolder >
  85. struct Getter
  86. {
  87. static RequestedType get(TContentHolder* holder)
  88. {
  89. cout << "getter 1" << endl;
  90. return Getter< RequestedType, typename TContentHolder::ContentType, typename TContentHolder::AdditionalContentTypes >::get(holder);
  91. }
  92. };
  93.  
  94. // specialized getter for when RequestedType matches ActualType: return value from holder
  95. template < class RequestedType, class TContentHolder >
  96. struct Getter< RequestedType, RequestedType, TContentHolder >
  97. {
  98. static RequestedType get(TContentHolder* holder)
  99. {
  100. cout << "getter 2" << endl;
  101. return holder->mVector[0];
  102. }
  103. };
  104.  
  105. // specialized getter for end of recursion
  106. template < class RequestedType >
  107. struct Getter< RequestedType, RequestedType, bool >
  108. {
  109. static RequestedType get(ContentHolder< RequestedType, bool >* holder)
  110. {
  111. cout << "getter 3" << endl;
  112. return holder->mVector[0];
  113. }
  114. };
  115.  
  116. // This is the getter in question
  117. template < class RequestedType, class NonMatchingType >
  118. struct Getter< RequestedType, NonMatchingType, bool >
  119. {
  120. static RequestedType get(ContentHolder< NonMatchingType, bool >* holder)
  121. {
  122. cout << "getter 4" << endl;
  123. //StaticAssert<false>::test("Type not in list");
  124. return 0;
  125. }
  126. };
  127.  
  128. class MyHolder : public ContentHolder< int, ContentHolder< bool, ContentHolder< char, bool > > >
  129. {
  130. };
  131.  
  132. int main() {
  133. MyHolder h;
  134. cout << h.get<int>() << endl;
  135. cout << h.get<bool>() << endl;
  136. cout << h.get<char>() << endl;
  137. //cout << h.get<float>() << endl;
  138. return 0;
  139. }
  140.  
Success #stdin #stdout 0s 3480KB
stdin
Standard input is empty
stdout
getter 2
75
getter 1
getter 1
getter 2
1
getter 1
getter 1
getter 1
getter 3
A