fork download
  1. #include <iostream>
  2. #include <map>
  3. #include <type_traits>
  4. #include <utility>
  5.  
  6. struct one {
  7. int foo(const int) { return 0; }
  8. int bar() const { return 0; }
  9. };
  10.  
  11. struct two {
  12. int foo(const int) { return 1; }
  13. };
  14.  
  15. struct three {
  16. int foo(const int) { return 2; }
  17. int bar() const { return 2; }
  18. };
  19.  
  20. template <class... Fs>
  21. struct overload_t;
  22.  
  23. // zero
  24. template<>
  25. struct overload_t<> {};
  26.  
  27. // >1
  28. template <class F0, class... Frest>
  29. struct overload_t<F0, Frest...> :
  30. F0,
  31. overload_t<Frest...>
  32. {
  33. overload_t(F0 f0, Frest... rest) :
  34. F0(std::move(f0)), overload_t<Frest...>(std::move(rest)...)
  35. {}
  36.  
  37. using F0::operator();
  38. using overload_t<Frest...>::operator();
  39. };
  40.  
  41. // 1
  42. template <class F0>
  43. struct overload_t<F0> : F0
  44. {
  45. overload_t(F0 f0) : F0(std::move(f0)) {}
  46.  
  47. using F0::operator();
  48. };
  49.  
  50. template <class... Fs>
  51. auto overload(Fs... fs)
  52. {
  53. return overload_t<Fs...>(std::move(fs)...);
  54. }
  55.  
  56. struct fallback_t { template<class T> fallback_t(T&&) {} };
  57.  
  58.  
  59. struct owner {
  60. std::map<int, one> ones;
  61. std::map<int, two> twos;
  62. std::map<int, three> threes;
  63.  
  64. template <typename T>
  65. int findObject(int key, const T& func) {
  66. if(ones.count(key) != 0U) {
  67. return func(ones[key]);
  68. }
  69. else if(twos.count(key) != 0U) {
  70. return func(twos[key]);
  71. }
  72. else {
  73. return func(threes[key]);
  74. }
  75. }
  76.  
  77. int foo(const int key, const int param) { return findObject(key, [&](auto& value) { return value.foo(param); }); }
  78. int bar(const int key) {
  79. return findObject(key, overload(
  80. [](auto&& value) -> decltype(value.bar()) {
  81. return value.bar();
  82. },
  83. [](fallback_t){ std::cout << "fallback\n"; return 13; }
  84. ));
  85. }
  86. };
  87.  
  88. int main() {
  89. owner myOwner;
  90.  
  91. myOwner.ones.insert(std::make_pair(0, one()));
  92. myOwner.twos.insert(std::make_pair(1, two()));
  93. myOwner.threes.insert(std::make_pair(2, three()));
  94.  
  95. myOwner.foo(2, 1);
  96. std::cout << myOwner.bar(1) << '\n';
  97. std::cout << myOwner.bar(2) << '\n';
  98. }
Success #stdin #stdout 0s 4556KB
stdin
Standard input is empty
stdout
fallback
13
2