#include #include template struct HasDeleteOperator { template struct SFINAE2 {}; template struct SFINAE1 {}; template static char Test(SFINAE1*); template static char Test(SFINAE2*); template static int Test(...); static const bool value = sizeof(Test(0)) == sizeof(char); }; template struct deleter { static void invoke(T *t) { std::cout << "Calling default operator delete" << std::endl; (operator delete)(t); } }; template struct deleter >::type> { template static void use_delete_operator(void * t, std::size_t s){ std::cout << "Calling class-specific operator delete with two arguments" << std::endl; D(t, s); } template static void use_delete_operator(void * t, std::size_t s){ std::cout << "Calling class-specific operator delete with one argument" << std::endl; D(t); } static void invoke(T *t) { use_delete_operator(t, sizeof(T)); } }; struct A { void operator delete(void *, std::size_t) {} }; struct B { void operator delete(void *) {} }; struct C { }; int main() { A *a = new A; deleter::invoke(a); B *b = new B; deleter::invoke(b); C *c = new C; deleter::invoke(c); }