#include <type_traits>
#include <iostream>

struct _test_print {
    template<class T> static auto test(T* p) -> decltype(p->print(), std::true_type());
    template<class>        static auto test(...) -> std::false_type;
};
template<class T> struct has_print : public decltype(_test_print::test<T>(0)) {};


template<typename T>
auto print(T t) -> typename std::enable_if<has_print<T>::value, decltype(t.print())>::type {
    return t.print();
}

template<typename T>
auto print(T t) -> typename std::enable_if<!has_print<T>::value, T>::type {
    return t;
}
    
    
struct MyClass {
    std::string print() {
        return "I was printed using my custom print()!";
    }
};
    
int main() {
    MyClass myobj;
    std::cout << print(42) << std::endl;
    std::cout << print(myobj) << std::endl;
}