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