#include <type_traits> using namespace std; struct A { public: A(){} static A& singleton() { static A obj; return obj; } private: A(const A&); A& operator=(A const&); }; struct A_1 { static A& singleton() { static A obj; return obj; } }; struct B { B& singleton() { return *this; } }; struct C { int singleton; }; void global_func(){} template<class T> struct is_function_pointer { private: template<class T> struct is_function_pointer_impl { typedef typename std::remove_pointer<T>::type pointee; typedef typename std::is_function<pointee>::type type; }; typedef typename std::conditional <std::is_pointer<T>::value, is_function_pointer_impl<T>, std::false_type> ::type cond_result_t; public: static const bool value = cond_result_t::type::value; }; template<typename T> struct has_singleton_accessor { private: typedef decltype(&T::singleton) func_t; public: static const bool value = is_function_pointer<func_t>::value && !std::is_member_function_pointer<func_t>::value; }; template<typename T> struct satisfy_singleton_requirement { enum { value = !std::is_trivially_copy_constructible<T>::value && !std::is_trivially_copy_assignable<T>::value }; }; template<typename T> struct is_singleton { static const bool value = has_singleton_accessor<T>::value && satisfy_singleton_requirement<T>::value; }; int main() { static_assert(is_function_pointer<decltype(&A::singleton)>::value, "true."); static_assert(is_function_pointer<decltype(&global_func)>::value, "also true."); static_assert(is_member_function_pointer<decltype(&B::singleton)>::value , "true."); static_assert(is_member_function_pointer<decltype(&A::singleton)>::value , "but it's false because A::singleton is the static member"); //therefore: static_assert(is_function_pointer<decltype(&A::singleton)>::value && !std::is_member_function_pointer<decltype(&A::singleton)>::value , "this is how to check whether A::singleton is static member function."); static_assert(is_singleton<A_1>::value, "this type isn't singleton."); //Err static_assert(is_singleton<B>::value, "this type isn't singleton."); //Err static_assert(is_singleton<C>::value, "this type isn't singleton."); //Err static_assert(is_singleton<A>::value, "that's it!"); }