#include <iostream>
#include <type_traits>
#include <utility>
// Utility
template <typename T, typename Result = void>
struct enable: std::enable_if< std::is_same<T, std::true_type>::value > {};
template <typename T, typename Result = void>
struct disable: std::enable_if< not std::is_same<T, std::true_type>::value > {};
// Hook
std::false_type has_specific_foo(...);
template <typename T>
auto foo(T const& t) -> typename disable<decltype(has_specific_foo(t))>::type {
std::cerr << "Generic case\n";
}
struct A{};
void foo(A const&) { std::cerr << "A\n"; }
std::true_type has_specific_foo(A const&);
struct B: A{};
int main() {
B b;
foo(b);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDx1dGlsaXR5PgoKICAgIC8vIFV0aWxpdHkKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSBSZXN1bHQgPSB2b2lkPgogICAgc3RydWN0IGVuYWJsZTogc3RkOjplbmFibGVfaWY8IHN0ZDo6aXNfc2FtZTxULCBzdGQ6OnRydWVfdHlwZT46OnZhbHVlID4ge307IAoKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSBSZXN1bHQgPSB2b2lkPgogICAgc3RydWN0IGRpc2FibGU6IHN0ZDo6ZW5hYmxlX2lmPCBub3Qgc3RkOjppc19zYW1lPFQsIHN0ZDo6dHJ1ZV90eXBlPjo6dmFsdWUgPiB7fTsgCgogICAgLy8gSG9vawogICAgc3RkOjpmYWxzZV90eXBlIGhhc19zcGVjaWZpY19mb28oLi4uKTsKIAogICAgdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CiAgICBhdXRvIGZvbyhUIGNvbnN0JiB0KSAtPiB0eXBlbmFtZSBkaXNhYmxlPGRlY2x0eXBlKGhhc19zcGVjaWZpY19mb28odCkpPjo6dHlwZSB7CiAgICAgIHN0ZDo6Y2VyciA8PCAiR2VuZXJpYyBjYXNlXG4iOwogICAgfQogCiAgICBzdHJ1Y3QgQXt9OwogCiAgICB2b2lkIGZvbyhBIGNvbnN0JikgeyBzdGQ6OmNlcnIgPDwgIkFcbiI7IH0KICAgIHN0ZDo6dHJ1ZV90eXBlIGhhc19zcGVjaWZpY19mb28oQSBjb25zdCYpOwogCiAgICBzdHJ1Y3QgQjogQXt9OwogCiAgICBpbnQgbWFpbigpIHsKICAgICAgQiBiOwogICAgICBmb28oYik7CiAgICB9