#include <iostream>
template <typename Func>
void apply(Func&& f, ...) { std::cout << "default\n"; }
template <typename Func, typename T>
auto apply(Func&& f, T&& t) -> decltype(f(std::forward<T>(t))) {
return f(std::forward<T>(t));
}
struct Foo {};
struct Bar {};
struct F {
void operator()(Foo) { std::cout << "Foo\n"; }
void operator()(Bar) { std::cout << "Bar\n"; }
};
int main() {
F f;
Foo foo;
Bar bar;
int i;
apply(f, foo);
apply(f, bar);
apply(f, i);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGUgPHR5cGVuYW1lIEZ1bmM+CnZvaWQgYXBwbHkoRnVuYyYmIGYsIC4uLikgeyBzdGQ6OmNvdXQgPDwgImRlZmF1bHRcbiI7IH0KCnRlbXBsYXRlIDx0eXBlbmFtZSBGdW5jLCB0eXBlbmFtZSBUPgphdXRvIGFwcGx5KEZ1bmMmJiBmLCBUJiYgdCkgLT4gZGVjbHR5cGUoZihzdGQ6OmZvcndhcmQ8VD4odCkpKSB7CiAgICByZXR1cm4gZihzdGQ6OmZvcndhcmQ8VD4odCkpOwp9CgoKc3RydWN0IEZvbyB7fTsKc3RydWN0IEJhciB7fTsKCnN0cnVjdCBGIHsKICAgIHZvaWQgb3BlcmF0b3IoKShGb28pIHsgc3RkOjpjb3V0IDw8ICJGb29cbiI7IH0KICAgIHZvaWQgb3BlcmF0b3IoKShCYXIpIHsgc3RkOjpjb3V0IDw8ICJCYXJcbiI7IH0KfTsKCmludCBtYWluKCkgewogICAgRiBmOwogICAgRm9vIGZvbzsKICAgIEJhciBiYXI7CiAgICBpbnQgaTsKICAgIGFwcGx5KGYsIGZvbyk7CiAgICBhcHBseShmLCBiYXIpOwogICAgYXBwbHkoZiwgaSk7Cn0=