fork download
  1. #include <iostream>
  2. #include <type_traits>
  3. #include <typeinfo>
  4.  
  5. template <class T> struct type_printer { static void print() { std::cout << typeid(T).name(); } };
  6. template <class T> struct type_printer<T const> { static void print() { type_printer<T>::print(); std::cout << " const"; } };
  7. template <class T> struct type_printer<T*> { static void print() { type_printer<T>::print(); std::cout << " *"; } };
  8. template <class T> struct type_printer<T&> { static void print() { type_printer<T>::print(); std::cout << " &"; } };
  9.  
  10. #define printtype(...) type_printer<__VA_ARGS__>::print()
  11. #define printtype_line(...) do { std::cout << #__VA_ARGS__ ": " << std::endl; printtype(__VA_ARGS__); std::cout << std::endl; } while (0)
  12.  
  13. template<typename Derived>
  14. struct base
  15. {
  16. void const_method() const
  17. {
  18. static_cast<Derived*>(this)->method();
  19. }
  20.  
  21. void fixed_const_method() const
  22. {
  23. // base<derived> const*
  24. printtype_line(decltype(this));
  25. // base<derived>
  26. printtype_line(typename std::remove_pointer<decltype(this)>::type);
  27. // base<derived>
  28. printtype_line(decltype(*this));
  29. // derived const*
  30. printtype_line(typename std::conditional<
  31. std::is_const<
  32. typename std::remove_pointer<decltype(this)>::type>::value,
  33. Derived const* const,
  34. Derived* const>::type);
  35.  
  36. static_cast<
  37. typename std::conditional<
  38. std::is_const<
  39. typename std::remove_pointer<decltype(this)>::type>::value,
  40. Derived const* const,
  41. Derived* const>::type>(this)->method();
  42. }
  43. };
  44.  
  45. struct derived : public base<derived>
  46. {
  47. void method() const
  48. {
  49. std::cout << "const method" << std::endl;
  50. }
  51.  
  52. void method()
  53. {
  54. std::cout << "non-const method" << std::endl;
  55. }
  56. };
  57.  
  58. int main()
  59. {
  60. derived d;
  61. d.fixed_const_method();
  62.  
  63. return 0;
  64. }
Success #stdin #stdout 0s 2856KB
stdin
Standard input is empty
stdout
decltype(this): 
4baseI7derivedE const *
typename std::remove_pointer<decltype(this)>::type: 
4baseI7derivedE const
decltype(*this): 
4baseI7derivedE const &
typename std::conditional< std::is_const< typename std::remove_pointer<decltype(this)>::type>::value, Derived const* const, Derived* const>::type: 
7derived const * const
const method