
Hi Vicente! On Sun, Nov 9, 2008 at 1:06 AM, vicente.botet <vicente.botet@wanadoo.fr> wrote: [snip]
Why the usual constructor is not enough -- init is called after active is constructed?
Good question. Actually, you're right. I got confused about the order of construction/destruction.
IMO static_cast<Derived*>(this)->destroy(); is very dangerous. You are calling a function for an object that has already been destructed, so any access to Derived data is undefined.
Again, you're right.
So ath the end whay do you need CRTP? Why do you need the usual constructor is not enough -- init is called after active is constructed?
It looks like CRTP is no longer needed. :-) So it will look something like this: template <class ThreadingPolicy> struct active : ThreadingPolicy { private: shared_ptr<io_service> queue; shared_ptr<io_service::work> sentinel; typename ThreadingPolicy::thread_type lifetime_thread; protected: active() : ThreadingPolicy(), queue(new io_service()), sentinel(new io_service::work(*queue)) { ThreadingPolicy::init_threading(lifetime_thread, queue); } ~active() { sentinel.reset(); ThreadingPolicy::destroy_threading(lifetime_thread); } void post(function<void()> f) { queue->post(ThreadingPolicy::wrap(f)); } }; Now the active object is no longer constrained to a single thread by choosing the correct policy. struct single_thread { protected: typedef shared_ptr<thread> thread_type; void init_threading(thread_type t, shared_ptr<io_service> q) { t.reset(new thread( bind(&io_service::run, q) ) ); } void destroy_threading(thread_type t) { t->join(); } function<void()> wrap(function<void()> f) { return f; } }; struct thread_pool { // ... }; Thanks for the insights, any interest in seeing something like this in Boost? -- Dean Michael C. Berris Software Engineer, Friendster, Inc.