fork download
  1. #include <iostream>
  2. #include <memory>
  3. #include <type_traits>
  4.  
  5. struct TagA {};
  6. struct TagB {};
  7.  
  8. template< typename tp_Derived >
  9. struct BaseCRTP;
  10.  
  11. struct Base
  12. {
  13. template< typename > friend
  14. struct BaseCRTP;
  15.  
  16. private: void
  17. handler_impl(const std::shared_ptr<Base> &) {}
  18. };
  19.  
  20. template< typename tp_Derived >
  21. struct BaseCRTP: public Base
  22. {
  23. public: void
  24. handler(const std::shared_ptr<Base> & obj)
  25. {
  26. static_assert
  27. (
  28. ::std::is_base_of< TagA, tp_Derived >::value
  29. , "\"handler\" method can only be used in classes deriving from TagA"
  30. );
  31. return(handler_impl(obj));
  32. }
  33. };
  34.  
  35. struct DerivedA : BaseCRTP< DerivedA >, TagA
  36. {};
  37.  
  38. struct DerivedB : BaseCRTP< DerivedB >, TagB
  39. {};
  40.  
  41. int main()
  42. {
  43. DerivedA a; // OK
  44. (void) a; // not used
  45. auto pha(&DerivedA::handler); // OK
  46. DerivedB b; // OK
  47. (void) b; // not used
  48. auto phb(&DerivedB::handler); // static_assertion failure
  49. return 0;
  50. }
Compilation error #stdin compilation error #stdout 0s 16064KB
stdin
Standard input is empty
compilation info
prog.cpp: In instantiation of ‘void BaseCRTP<tp_Derived>::handler(const std::shared_ptr<Base>&) [with tp_Derived = DerivedB]’:
prog.cpp:48:22:   required from here
prog.cpp:26:3: error: static assertion failed: "handler" method can only be used in classes deriving from TagA
   static_assert
   ^~~~~~~~~~~~~
stdout
Standard output is empty