
Anthony Williams wrote:
Alexander Terekhov <terekhov@web.de> writes:
Anthony Williams wrote:
However, our once_flag can store a result of a user-defined type, which may therefore require proper destruction, so that it can notify other processes, send network packets, write to a file, or whatever; this therefore needs dealing with somehow before process termination.
User would then call _destroy() or _reset() (the later is likely to be called multiple times). I won't tell you "how". Trade secret.
Don't be such a tease!
class X { public X() { acquire_resource(); } void do_something(); ~X() { release_resource(); } };
X get_X();
void f() { static once_flag once; call_once(get_X,once).do_something(); // how do we clean up the X associated with "once", and release it's // resource? // We can't sensibly call once_destroy() here. }
I have written a static_<...> template class that uses boost::call_once to (I suppose) offer thread-safe initialization of what amounts to static data. Use case: void f() { static_<X> x; } This seems equal in purpose to what you're now seeking to offer with the new call_once. Here's the abbreviated implementation of static_, template < ... > struct static_ { static_() { struct constructor { static void construct() { new (get_address()) value_type(); // Schedule the object for destruction static destructor d; } }; // Ensure constructor is called only once boost::call_once(&constructor::construct, constructed_); } private: static pointer get_address() { return static_cast<pointer>(data_.address()); } struct destructor { ~destructor() { get_address()->~value_type(); } }; // static storage for object and flag static boost::aligned_storage< ... > data_; static boost::once_flag constructed_; }; I'd like to hear your views on the flaws and shortcomings with this approach. Regards, João