#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;
}
operator int() const
{
return 32;
}
};
struct Bar
{
std::string print()
{
return "The answer...";
}
operator int() const
{
return (int)Foo();
}
};
struct Baz
{
operator std::string() const
{
return std::string("The answer...");
}
};
int main()
{
std::cout << print(Foo()) << std::endl;
std::cout << print(Bar()) << std::endl;
std::cout << print(42) << std::endl;
std::cout << print((int)Foo()) << std::endl;
std::cout << print("The answer...") << std::endl;
std::cout << print(std::string("The answer...")) << std::endl;
std::cout << print((int)Bar()) << std::endl;
std::cout << print((std::string)Baz()) << std::endl;
}
ICAgICNpbmNsdWRlIDxzdHJpbmc+CiAgICAjaW5jbHVkZSA8aW9zdHJlYW0+CiAgICAjaW5jbHVkZSA8dHlwZV90cmFpdHM+CgogICAgbmFtZXNwYWNlIGRldGFpbAogICAgewogICAgICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lID0gdm9pZD4KICAgICAgICBzdHJ1Y3QgcHJpbnRfaGVscGVyCiAgICAgICAgewogICAgICAgICAgICBzdGF0aWMgVCBwcmludChUIHQpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICAgICAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KICAgICAgICBzdHJ1Y3QgcHJpbnRfaGVscGVyPFQsIGRlY2x0eXBlKHN0ZDo6ZGVjbHZhbDxUPigpLnByaW50KCksICh2b2lkKTApPgogICAgICAgIHsKICAgICAgICAgICAgc3RhdGljIGF1dG8gcHJpbnQoVCB0KSAtPiBkZWNsdHlwZSh0LnByaW50KCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0LnByaW50KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfQoKICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CiAgICBhdXRvIHByaW50KFQgdCkgLT4gZGVjbHR5cGUoZGV0YWlsOjpwcmludF9oZWxwZXI8VD46OnByaW50KHQpKQogICAgewogICAgICAgIHJldHVybiBkZXRhaWw6OnByaW50X2hlbHBlcjxUPjo6cHJpbnQodCk7CiAgICB9CgogICAgc3RydWN0IEZvbwogICAgewogICAgICAgIGludCBwcmludCgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gNDI7CiAgICAgICAgfQoKICAgICAgICBvcGVyYXRvciBpbnQoKSBjb25zdAogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIDMyOwogICAgICAgIH0KICAgIH07CgogICAgc3RydWN0IEJhcgogICAgewogICAgICAgIHN0ZDo6c3RyaW5nIHByaW50KCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAiVGhlIGFuc3dlci4uLiI7CiAgICAgICAgfQoKICAgICAgICBvcGVyYXRvciBpbnQoKSBjb25zdAogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIChpbnQpRm9vKCk7CiAgICAgICAgfQogICAgfTsKCiAgICBzdHJ1Y3QgQmF6CiAgICB7CiAgICAgICAgb3BlcmF0b3Igc3RkOjpzdHJpbmcoKSBjb25zdAogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHN0ZDo6c3RyaW5nKCJUaGUgYW5zd2VyLi4uIik7CiAgICAgICAgfQogICAgfTsKCiAgICBpbnQgbWFpbigpCiAgICB7CiAgICAgICAgc3RkOjpjb3V0IDw8IHByaW50KEZvbygpKSA8PCBzdGQ6OmVuZGw7CiAgICAgICAgc3RkOjpjb3V0IDw8IHByaW50KEJhcigpKSA8PCBzdGQ6OmVuZGw7CiAgICAgICAgc3RkOjpjb3V0IDw8IHByaW50KDQyKSA8PCBzdGQ6OmVuZGw7CiAgICAgICAgc3RkOjpjb3V0IDw8IHByaW50KChpbnQpRm9vKCkpIDw8IHN0ZDo6ZW5kbDsKICAgICAgICBzdGQ6OmNvdXQgPDwgcHJpbnQoIlRoZSBhbnN3ZXIuLi4iKSA8PCBzdGQ6OmVuZGw7CiAgICAgICAgc3RkOjpjb3V0IDw8IHByaW50KHN0ZDo6c3RyaW5nKCJUaGUgYW5zd2VyLi4uIikpIDw8IHN0ZDo6ZW5kbDsKICAgICAgICBzdGQ6OmNvdXQgPDwgcHJpbnQoKGludClCYXIoKSkgPDwgc3RkOjplbmRsOwogICAgICAgIHN0ZDo6Y291dCA8PCBwcmludCgoc3RkOjpzdHJpbmcpQmF6KCkpIDw8IHN0ZDo6ZW5kbDsKICAgIH0K