#include <iostream>
#include <map>
#include <type_traits>
#include <utility>
struct one {
int foo(const int) { return 0; }
int bar() const { return 0; }
};
struct two {
int foo(const int) { return 1; }
};
struct three {
int foo(const int) { return 2; }
int bar() const { return 2; }
};
template <class... Fs>
struct overload_t;
// zero
template<>
struct overload_t<> {};
// >1
template <class F0, class... Frest>
struct overload_t<F0, Frest...> :
F0,
overload_t<Frest...>
{
overload_t(F0 f0, Frest... rest) :
F0(std::move(f0)), overload_t<Frest...>(std::move(rest)...)
{}
using F0::operator();
using overload_t<Frest...>::operator();
};
// 1
template <class F0>
struct overload_t<F0> : F0
{
overload_t(F0 f0) : F0(std::move(f0)) {}
using F0::operator();
};
template <class... Fs>
auto overload(Fs... fs)
{
return overload_t<Fs...>(std::move(fs)...);
}
struct fallback_t { template<class T> fallback_t(T&&) {} };
struct owner {
std::map<int, one> ones;
std::map<int, two> twos;
std::map<int, three> threes;
template <typename T>
int findObject(int key, const T& func) {
if(ones.count(key) != 0U) {
return func(ones[key]);
}
else if(twos.count(key) != 0U) {
return func(twos[key]);
}
else {
return func(threes[key]);
}
}
int foo(const int key, const int param) { return findObject(key, [&](auto& value) { return value.foo(param); }); }
int bar(const int key) {
return findObject(key, overload(
[](auto&& value) -> decltype(value.bar()) {
return value.bar();
},
[](fallback_t){ std::cout << "fallback\n"; return 13; }
));
}
};
int main() {
owner myOwner;
myOwner.ones.insert(std::make_pair(0, one()));
myOwner.twos.insert(std::make_pair(1, two()));
myOwner.threes.insert(std::make_pair(2, three()));
myOwner.foo(2, 1);
std::cout << myOwner.bar(1) << '\n';
std::cout << myOwner.bar(2) << '\n';
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWFwPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDx1dGlsaXR5PgoKc3RydWN0IG9uZSB7CiAgaW50IGZvbyhjb25zdCBpbnQpIHsgcmV0dXJuIDA7IH0KICBpbnQgYmFyKCkgY29uc3QgeyByZXR1cm4gMDsgfQp9OwoKc3RydWN0IHR3byB7CiAgaW50IGZvbyhjb25zdCBpbnQpIHsgcmV0dXJuIDE7IH0KfTsKCnN0cnVjdCB0aHJlZSB7CiAgaW50IGZvbyhjb25zdCBpbnQpIHsgcmV0dXJuIDI7IH0KICBpbnQgYmFyKCkgY29uc3QgeyByZXR1cm4gMjsgfQp9OwoKdGVtcGxhdGUgPGNsYXNzLi4uIEZzPgpzdHJ1Y3Qgb3ZlcmxvYWRfdDsKCi8vIHplcm8KdGVtcGxhdGU8PgpzdHJ1Y3Qgb3ZlcmxvYWRfdDw+IHt9OwoKLy8gPjEKdGVtcGxhdGUgPGNsYXNzIEYwLCBjbGFzcy4uLiBGcmVzdD4Kc3RydWN0IG92ZXJsb2FkX3Q8RjAsIEZyZXN0Li4uPiA6CiAgRjAsCiAgb3ZlcmxvYWRfdDxGcmVzdC4uLj4KewogICAgb3ZlcmxvYWRfdChGMCBmMCwgRnJlc3QuLi4gcmVzdCkgOgogICAgICBGMChzdGQ6Om1vdmUoZjApKSwgb3ZlcmxvYWRfdDxGcmVzdC4uLj4oc3RkOjptb3ZlKHJlc3QpLi4uKQogICB7fQoKICAgIHVzaW5nIEYwOjpvcGVyYXRvcigpOwogICAgdXNpbmcgb3ZlcmxvYWRfdDxGcmVzdC4uLj46Om9wZXJhdG9yKCk7Cn07CgovLyAxCnRlbXBsYXRlIDxjbGFzcyBGMD4Kc3RydWN0IG92ZXJsb2FkX3Q8RjA+IDogRjAKewogICAgb3ZlcmxvYWRfdChGMCBmMCkgOiBGMChzdGQ6Om1vdmUoZjApKSB7fQoKICAgIHVzaW5nIEYwOjpvcGVyYXRvcigpOwp9OwoKdGVtcGxhdGUgPGNsYXNzLi4uIEZzPgphdXRvIG92ZXJsb2FkKEZzLi4uIGZzKQp7CiAgcmV0dXJuIG92ZXJsb2FkX3Q8RnMuLi4+KHN0ZDo6bW92ZShmcykuLi4pOwp9CgpzdHJ1Y3QgZmFsbGJhY2tfdCB7IHRlbXBsYXRlPGNsYXNzIFQ+IGZhbGxiYWNrX3QoVCYmKSB7fSB9OwoKCnN0cnVjdCBvd25lciB7CiAgc3RkOjptYXA8aW50LCBvbmU+IG9uZXM7CiAgc3RkOjptYXA8aW50LCB0d28+IHR3b3M7CiAgc3RkOjptYXA8aW50LCB0aHJlZT4gdGhyZWVzOwoKICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KICBpbnQgZmluZE9iamVjdChpbnQga2V5LCBjb25zdCBUJiBmdW5jKSB7CiAgICBpZihvbmVzLmNvdW50KGtleSkgIT0gMFUpIHsKICAgICAgcmV0dXJuIGZ1bmMob25lc1trZXldKTsKICAgIH0KICAgIGVsc2UgaWYodHdvcy5jb3VudChrZXkpICE9IDBVKSB7CiAgICAgIHJldHVybiBmdW5jKHR3b3Nba2V5XSk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgcmV0dXJuIGZ1bmModGhyZWVzW2tleV0pOwogICAgfQogIH0KCiAgaW50IGZvbyhjb25zdCBpbnQga2V5LCBjb25zdCBpbnQgcGFyYW0pIHsgcmV0dXJuIGZpbmRPYmplY3Qoa2V5LCBbJl0oYXV0byYgdmFsdWUpIHsgcmV0dXJuIHZhbHVlLmZvbyhwYXJhbSk7IH0pOyB9CiAgaW50IGJhcihjb25zdCBpbnQga2V5KSB7CiAgICByZXR1cm4gZmluZE9iamVjdChrZXksIG92ZXJsb2FkKAogICAgICBbXShhdXRvJiYgdmFsdWUpIC0+IGRlY2x0eXBlKHZhbHVlLmJhcigpKSB7CiAgICAgIAlyZXR1cm4gdmFsdWUuYmFyKCk7CiAgICAgIH0sCiAgICAgIFtdKGZhbGxiYWNrX3QpeyBzdGQ6OmNvdXQgPDwgImZhbGxiYWNrXG4iOyByZXR1cm4gMTM7IH0KICAgICAgKSk7CiAgfQp9OwoKaW50IG1haW4oKSB7CiAgb3duZXIgbXlPd25lcjsKCiAgbXlPd25lci5vbmVzLmluc2VydChzdGQ6Om1ha2VfcGFpcigwLCBvbmUoKSkpOwogIG15T3duZXIudHdvcy5pbnNlcnQoc3RkOjptYWtlX3BhaXIoMSwgdHdvKCkpKTsKICBteU93bmVyLnRocmVlcy5pbnNlcnQoc3RkOjptYWtlX3BhaXIoMiwgdGhyZWUoKSkpOwoKICBteU93bmVyLmZvbygyLCAxKTsKICBzdGQ6OmNvdXQgPDwgbXlPd25lci5iYXIoMSkgPDwgJ1xuJzsKICBzdGQ6OmNvdXQgPDwgbXlPd25lci5iYXIoMikgPDwgJ1xuJzsKfQ==