fork download
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. enum class kTypeFlag { PARENTONE, PARENTTWO, CHILD };
  5.  
  6. class ParentOne {
  7. public:
  8. ParentOne() { }
  9. virtual ~ParentOne() { }
  10. virtual size_t byte_size() const = 0;
  11. };
  12.  
  13. class ParentTwo {
  14. public:
  15. ParentTwo(uint32_t id) : id_(id) { }
  16. virtual ~ParentTwo() { }
  17. uint32_t id() const { return id_; }
  18. private:
  19. const uint32_t id_;
  20. };
  21.  
  22. class Child : public ParentOne, public ParentTwo {
  23. public:
  24. Child(uint32_t id) : ParentOne(), ParentTwo(id) { }
  25. virtual ~Child() { }
  26. size_t byte_size() const override { return sizeof(*this); }
  27. };
  28.  
  29. namespace details
  30. {
  31. template<typename To, kTypeFlag>
  32. struct cex {To* operator()() {
  33. static_assert(!std::is_same<To, To>::value, "invalid flag to Convert");} };
  34.  
  35. template<typename To>
  36. struct cex<To, kTypeFlag::PARENTONE> { To* operator()(void*p) {
  37. return static_cast<To*>(static_cast<ParentOne*>(p)); } };
  38.  
  39. template<typename To>
  40. struct cex<To, kTypeFlag::PARENTTWO> { To* operator()(void*p) {
  41. return static_cast<To*>(static_cast<ParentTwo*>(p)); } };
  42.  
  43. template<typename To>
  44. struct cex<To, kTypeFlag::CHILD> { To* operator()(void*p) {
  45. return static_cast<To*>(static_cast<Child*>(p)); } };
  46. };
  47.  
  48. template <typename T, kTypeFlag Flag>
  49. T* ConvertEx (void* pointer)
  50. {
  51. return details::cex<T, Flag>()(pointer);
  52. }
  53.  
  54. int main()
  55. {
  56. Child* child = new Child(5);
  57. printf("byte_size: %zu\n", child->byte_size());
  58. printf("id: %u\n", child->id());
  59.  
  60. ParentOne* p1 = ConvertEx<ParentOne, kTypeFlag::CHILD>(child);
  61. ParentTwo* p2 = ConvertEx<ParentTwo, kTypeFlag::CHILD>(child);
  62. printf("byte_size: %zu\n", p1->byte_size());
  63. printf("id: %u\n", p2->id());
  64.  
  65.  
  66. return 0;
  67. }
Success #stdin #stdout 0s 3460KB
stdin
Standard input is empty
stdout
byte_size: 12
id: 5
byte_size: 12
id: 5