#include <iostream>
#include <type_traits>
 
struct Printable {};
struct Serializable {};
struct DerivedPrintable : Printable {};
struct DerivedSerializable : Serializable {};
 
template <class T, typename std::enable_if<std::is_base_of<Printable, T>::value>::type* = nullptr>
void print(const T& value) {
    std::cout << "printable(" << &value << ")\n";
}

template <class T, typename std::enable_if<std::is_base_of<Serializable, T>::value>::type* = nullptr>
void print(const T& value) {
    std::cout << "serializable(" << &value << ")\n";
} 
 
int main() {
    print(Printable());
    print(DerivedPrintable());
    print(Serializable());
    print(DerivedSerializable());
}
