#include <string>
#include <iostream>
#include <type_traits>
namespace detail
{
template<typename T, typename = void>
struct print_helper
{
static T print(T t) {
return t;
}
};
template<typename T>
struct print_helper<T, decltype(std::declval<T>().print(), (void)0)>
{
static auto print(T t) -> decltype(t.print()) {
return t.print();
}
};
}
template<typename T>
auto print(T t) -> decltype(detail::print_helper<T>::print(t))
{
return detail::print_helper<T>::print(t);
}
struct Foo
{
int print()
{
return 42;
}
};
struct Bar
{
std::string print()
{
return "The answer...";
}
};
struct Baz
{
int print() { return 1729; };
operator int() const
{
return 42;
}
};
int main()
{
Foo foo;
Bar bar;
Baz baz;
static_assert(std::is_same<decltype(print(foo)), int>::value, "!");
std::cout << print(foo) << std::endl;
std::cout << print(bar) << std::endl;
std::cout << print(baz) << std::endl;
std::cout << print(42) << std::endl;
}
ICAgICNpbmNsdWRlIDxzdHJpbmc+CiAgICAjaW5jbHVkZSA8aW9zdHJlYW0+CiAgICAjaW5jbHVkZSA8dHlwZV90cmFpdHM+CgogICAgbmFtZXNwYWNlIGRldGFpbAogICAgewogICAgICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lID0gdm9pZD4KICAgICAgICBzdHJ1Y3QgcHJpbnRfaGVscGVyCiAgICAgICAgewogICAgICAgICAgICBzdGF0aWMgVCBwcmludChUIHQpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICAgICAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KICAgICAgICBzdHJ1Y3QgcHJpbnRfaGVscGVyPFQsIGRlY2x0eXBlKHN0ZDo6ZGVjbHZhbDxUPigpLnByaW50KCksICh2b2lkKTApPgogICAgICAgIHsKICAgICAgICAgICAgc3RhdGljIGF1dG8gcHJpbnQoVCB0KSAtPiBkZWNsdHlwZSh0LnByaW50KCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0LnByaW50KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfQoKICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CiAgICBhdXRvIHByaW50KFQgdCkgLT4gZGVjbHR5cGUoZGV0YWlsOjpwcmludF9oZWxwZXI8VD46OnByaW50KHQpKQogICAgewogICAgICAgIHJldHVybiBkZXRhaWw6OnByaW50X2hlbHBlcjxUPjo6cHJpbnQodCk7CiAgICB9CgogICAgc3RydWN0IEZvbwogICAgewogICAgICAgIGludCBwcmludCgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gNDI7CiAgICAgICAgfQogICAgfTsKCiAgICBzdHJ1Y3QgQmFyCiAgICB7CiAgICAgICAgc3RkOjpzdHJpbmcgcHJpbnQoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuICJUaGUgYW5zd2VyLi4uIjsKICAgICAgICB9CiAgICB9OwoKICAgIHN0cnVjdCBCYXoKICAgIHsKICAgICAgICBpbnQgcHJpbnQoKSB7IHJldHVybiAxNzI5OyB9OwogICAgICAgIG9wZXJhdG9yIGludCgpIGNvbnN0CiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gNDI7CiAgICAgICAgfQogICAgfTsKCiAgICBpbnQgbWFpbigpCiAgICB7CiAgICAgICAgRm9vIGZvbzsKICAgICAgICBCYXIgYmFyOwogICAgICAgIEJheiBiYXo7CgogICAgICAgIHN0YXRpY19hc3NlcnQoc3RkOjppc19zYW1lPGRlY2x0eXBlKHByaW50KGZvbykpLCBpbnQ+Ojp2YWx1ZSwgIiEiKTsKCiAgICAgICAgc3RkOjpjb3V0IDw8IHByaW50KGZvbykgPDwgc3RkOjplbmRsOwogICAgICAgIHN0ZDo6Y291dCA8PCBwcmludChiYXIpIDw8IHN0ZDo6ZW5kbDsKICAgICAgICBzdGQ6OmNvdXQgPDwgcHJpbnQoYmF6KSA8PCBzdGQ6OmVuZGw7CiAgICAgICAgc3RkOjpjb3V0IDw8IHByaW50KDQyKSA8PCBzdGQ6OmVuZGw7CiAgICB9Cg==