#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!"); }
Category: C++
C++11 thread 객체를 static 또는 전역에서 선언했을 때 발생하는 deadlock
참고 : http://stackoverflow.com/questions/10915233/stdthreadjoin-hangs-if-called-after-main-exits-when-using-vs2012-rc
std::thread 객체를 Windows에서 static으로 사용하는 경우.
join을 호출하면 내부 API가 락을 시도하는데, 프로세스 종료 시점에서 join을 시도하면,
- main() 이 반환된다.
- 메인스레드가 종료를 위해 프로세스 내부적으로 사용되는 특정한 lock을 건다.
- 전역 객체들에 대해 소멸자를 호출하는데 소멸자가 std::thread::join을 호출한다면,
- child 스레드가 자신의 종료를 위해 프로세스에 lock을 시도하는데 이미 메인스레드가 lock을 잡고있다.
- DEADLOCK.
스택오버플로의 게시물에 의하면 Windows에서만 발생하는 문제인 것 같다.
C++11의 레이아웃 개념
http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special/7189821
POD로부터 분리된 trivial, standard layout에 대한 설명글.