#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;
}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8aW9zdHJlYW0+CgpzdHJ1Y3QgX3Rlc3RfcHJpbnQgewogICAgdGVtcGxhdGU8Y2xhc3MgVD4gc3RhdGljIGF1dG8gdGVzdChUKiBwKSAtPiBkZWNsdHlwZShwLT5wcmludCgpLCBzdGQ6OnRydWVfdHlwZSgpKTsKICAgIHRlbXBsYXRlPGNsYXNzPiAgICAgICAgc3RhdGljIGF1dG8gdGVzdCguLi4pIC0+IHN0ZDo6ZmFsc2VfdHlwZTsKfTsKdGVtcGxhdGU8Y2xhc3MgVD4gc3RydWN0IGhhc19wcmludCA6IHB1YmxpYyBkZWNsdHlwZShfdGVzdF9wcmludDo6dGVzdDxUPigwKSkge307CgoKdGVtcGxhdGU8dHlwZW5hbWUgVD4KYXV0byBwcmludChUIHQpIC0+IHR5cGVuYW1lIHN0ZDo6ZW5hYmxlX2lmPGhhc19wcmludDxUPjo6dmFsdWUsIGRlY2x0eXBlKHQucHJpbnQoKSk+Ojp0eXBlIHsKICAgIHJldHVybiB0LnByaW50KCk7Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CmF1dG8gcHJpbnQoVCB0KSAtPiB0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjwhaGFzX3ByaW50PFQ+Ojp2YWx1ZSwgVD46OnR5cGUgewogICAgcmV0dXJuIHQ7Cn0KICAgIAogICAgCnN0cnVjdCBNeUNsYXNzIHsKICAgIHN0ZDo6c3RyaW5nIHByaW50KCkgewogICAgICAgIHJldHVybiAiSSB3YXMgcHJpbnRlZCB1c2luZyBteSBjdXN0b20gcHJpbnQoKSEiOwogICAgfQp9OwogICAgCmludCBtYWluKCkgewogICAgTXlDbGFzcyBteW9iajsKICAgIHN0ZDo6Y291dCA8PCBwcmludCg0MikgPDwgc3RkOjplbmRsOwogICAgc3RkOjpjb3V0IDw8IHByaW50KG15b2JqKSA8PCBzdGQ6OmVuZGw7Cn0=