fork(3) download
  1. #include <iostream>
  2. #include <string>
  3. #include <memory>
  4. #include <utility>
  5. #include <cassert>
  6.  
  7. #define GENERATE_META(type) \
  8.   public: \
  9.   static const MetaInfo& StaticMeta() \
  10.   { \
  11.   static MetaInfo meta{#type}; \
  12.   return meta; \
  13.   }
  14.  
  15. struct MetaInfo
  16. {
  17. const std::string _id;
  18.  
  19. explicit MetaInfo( std::string ti )
  20. : _id{std::move( ti )}{}
  21.  
  22. bool operator==(const MetaInfo& rhs) const
  23. {
  24. return _id == rhs._id;
  25. }
  26.  
  27. bool operator!=(const MetaInfo& rhs) const
  28. {
  29. return operator==(rhs);
  30. }
  31. };
  32.  
  33. // Inheritance is just for example
  34. // In real project code is generated by tools
  35. struct Base
  36. {
  37. protected:
  38. Base() = default;
  39. };
  40.  
  41. struct MyType1 : Base
  42. {
  43. GENERATE_META(MyType1)
  44. int _dummy = 1;
  45. };
  46.  
  47. struct MyType2 : Base
  48. {
  49. GENERATE_META(MyType2)
  50. float _dummy = 2.f;
  51. };
  52.  
  53. struct MyType3 : Base
  54. {
  55. GENERATE_META(MyType3)
  56. std::string _dummy = "gg";
  57. };
  58.  
  59.  
  60. class Table
  61. {
  62. public:
  63. template< typename T >
  64. static Table Create()
  65. {
  66. auto data = std::make_shared<T>();
  67. auto meta = &T::StaticMeta();
  68. return { data, meta };
  69. }
  70.  
  71. const std::shared_ptr<Base>& Data() const{ return _data; }
  72. const MetaInfo& Meta() const{ return *_meta; }
  73.  
  74. private:
  75. Table( std::shared_ptr<Base> data, const MetaInfo * meta )
  76. : _data{std::move(data)}
  77. , _meta{meta}
  78. {}
  79.  
  80. private:
  81. std::shared_ptr<Base> _data;
  82. const MetaInfo * const _meta = nullptr;
  83. };
  84.  
  85. template< typename T >
  86. void Print( const Table& table )
  87. {
  88. assert( table.Meta() == T::StaticMeta() );
  89. const auto& data = *static_cast<T*>(table.Data().get());
  90. std::cout << table.Meta()._id << " -> " << data._dummy << "\n";
  91. }
  92.  
  93. /////////////////////////////////////////////////////////////////////
  94.  
  95. template< typename T >
  96. bool Validate( const Table& table )
  97. {
  98. if ( table.Meta() == T::StaticMeta() )
  99. {
  100. Print<T>( table );
  101. return true;
  102. }
  103.  
  104. return false;
  105. }
  106.  
  107. template< typename T, typename ...Tables >
  108. bool Validate( const Table& table )
  109. {
  110. if ( Validate<T>( table ) )
  111. return true;
  112.  
  113. return Validate<Tables...>(table);
  114. }
  115.  
  116.  
  117. int main()
  118. {
  119. const auto t1 = Table::Create<MyType1>();
  120. const auto t2 = Table::Create<MyType2>();
  121. const auto t3 = Table::Create<MyType3>();
  122.  
  123. const auto r1 = Validate<MyType1, MyType2>(t1);
  124. assert( r1 );
  125. const auto r2 = Validate<MyType1, MyType2>(t2);
  126. assert( r2 );
  127. const auto r3 = Validate<MyType1, MyType2>(t3);
  128. assert( !r3 );
  129.  
  130. return 0;
  131. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp: In instantiation of ‘bool Validate(const Table&) [with T = MyType1; Tables = {MyType2}]’:
prog.cpp:123:50:   required from here
prog.cpp:110:21: error: call of overloaded ‘Validate(const Table&)’ is ambiguous
     if ( Validate<T>( table ) )
          ~~~~~~~~~~~^~~~~~~~~
prog.cpp:96:6: note: candidate: bool Validate(const Table&) [with T = MyType1]
 bool Validate( const Table& table )
      ^~~~~~~~
prog.cpp:108:6: note: candidate: bool Validate(const Table&) [with T = MyType1; Tables = {}]
 bool Validate( const Table& table )
      ^~~~~~~~
prog.cpp:113:31: error: call of overloaded ‘Validate(const Table&)’ is ambiguous
     return Validate<Tables...>(table);
            ~~~~~~~~~~~~~~~~~~~^~~~~~~
prog.cpp:96:6: note: candidate: bool Validate(const Table&) [with T = MyType2]
 bool Validate( const Table& table )
      ^~~~~~~~
prog.cpp:108:6: note: candidate: bool Validate(const Table&) [with T = MyType2; Tables = {}]
 bool Validate( const Table& table )
      ^~~~~~~~
stdout
Standard output is empty