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