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