#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);
}