#include <stdio.h>
#include <type_traits>

void print()
{
    printf("cheers from print !\n");
}

class A 
{
  public:
  void print()
  {
      printf("cheers from A !\n");
  }
};

template<typename Function>
void run(Function& f, std::true_type tag)
{
   f();
}

template<typename Object>
void run(Object& o, std::false_type tag)
{
   o.print();
}


template<typename T>
void run(T& t)
{
   constexpr bool is_fun = std::is_function<typename std::remove_pointer<T>::type >::value;
   run(t, std::integral_constant<bool, is_fun>());
}

int main()
{
    run(print);

    A a;
    run(a);

    return 0;
}
