fork download
  1. #include <string>
  2. #include <utility>
  3. #include <functional>
  4. #include <iostream>
  5.  
  6. namespace detail
  7. {
  8. template<typename T, typename U, typename = void>
  9. struct maybe_call_init
  10. {
  11. static void maybe_call(U* obj) { }
  12. };
  13.  
  14. template<typename T, typename U>
  15. struct maybe_call_init<T, U,
  16. decltype(T::Init(std::declval<U*>()), void(0))>
  17. {
  18. static void maybe_call(U* obj) { T::Init(obj); }
  19. };
  20. }
  21.  
  22. template<template<typename> class T, typename U>
  23. void maybe_call_init(T<U>* obj)
  24. {
  25. detail::maybe_call_init<U, T<U>>::maybe_call(obj);
  26. }
  27.  
  28. template<typename Traits>
  29. class Test
  30. {
  31. public:
  32. Test()
  33. {
  34. maybe_call_init(this);
  35. }
  36.  
  37. public:
  38. typename Traits::Type value;
  39.  
  40. friend Traits;
  41. };
  42.  
  43. struct TestTraits
  44. {
  45. typedef std::string Type;
  46. };
  47.  
  48. struct TestTraitsInit
  49. {
  50. typedef int Type;
  51.  
  52. static void Init(Test<TestTraitsInit>* obj)
  53. {
  54. obj->value = 42;
  55. }
  56. };
  57.  
  58. int main()
  59. {
  60. Test<TestTraits> obj1;
  61. std::cout << "Value of obj1: " << obj1.value << std::endl;
  62. Test<TestTraitsInit> obj2;
  63. std::cout << "Value of obj2: " << obj2.value << std::endl;
  64. }
  65.  
Success #stdin #stdout 0s 2896KB
stdin
Standard input is empty
stdout
Value of obj1: 
Value of obj2: 42