----- Original Message ----- From: "Anthony Williams" <[EMAIL PROTECTED]> To: "Boost mailing list" <[EMAIL PROTECTED]> Sent: Thursday, February 13, 2003 7:05 AM Subject: Re: [boost] 'optional' - request for extension
> Aleksey Gurtovoy writes: > > > > The following is a sketch of a potential use case for the newly-accepted and > > already very useful 'optional' class. > > I'm glad to see optional<> being already exercised! > > Suppose you have a pure RAII guard/locker which unconditionally does its > > job: > > > > struct RAII_lock > > : boost::noncopyable > > { > > RAII_lock(entity& e); > > ~RAII_lock(); > > }; > > > > and you want to write a semantic equivalent to the following > > > > boost::scoped_ptr<RAII_lock> lock( cond ? new RAII_lock(entity) : 0 ); > > // ... > > > > expect for the dynamic allocation part. How would you do it? > > > > IMO the following seems only natural: > > > > boost::optional<RAII_lock> lock( cond, entity ); > > // ... > > > > The only problem with the above is that currently you cannot write something > > like this. It would be nice if we could, IMO. > > > > Thoughts? > OK, I can see the motivation: We can have a noncopyable class and need an optional object of it. Following optional semantics, it would be spelled: boost::optional<RAII_lock> lock; if ( cond ) lock.reset( RAII_lock(entity) ) ; But there is a probem: as William pointed out, reset() _needs_ to use T::T(T const&) in order acquire its own copy of the object; but in this case is noncopyable, so the above won't compile. > * Firstly, this would require optional to be able hold non-copy-constructible > types, whereas the current requirement say "T must be CopyConstructible". > Indeed. > You could drop the "CopyConstructible" requirement if you said that > boost::optional<T> is only itself CopyConstructible/Assignable/Swappable if T > is CopyConstructible. Right. >However, this leaves the question of how to get the > value in there in the first place; the answer to which is ... > With the current implementation it is possible to construct the contained object in-place. > * Secondly, you would need a templated constructor to allow T to be constructed > using another type. > Exactly. One possibility would be add additional templated ctor and reset that just forward the arguments to T's contructor (optional's interface could use a trailing tag to differentiate these). A problem with this is that the Argument Forwarding problem is burried into optional's itself. Another approach would be to create a generic delay-factory object and just let optional use it: Something like: template<class T, class A0> struct in_place_factory0 { in_place_factory0 ( A0& a0_ ) : a0(a0_) {} T* operator() ( void* address ) const { return new (address) T(a0) ; } A0& a0 ; } ; template<class T, class A0> in_place_factory0<T,A0> in_place ( A0& a0 ) { return in_place_factory0<T,A0>(a0) ; } which requires the following changes in optional<>: template<class T> class optional { public : .... template<class Factory> explicit optional ( Factory f ) : m_initialized(false) { construct_inplace(f); } ... private : template<class Factory> void construct_inplace ( Factory f ) { f(m_storage.address()); m_initialized = true ; } } ; The above would allow something like this: optional<RAII_lock> l( in_place<RAII_lock>(entity) ); If the same in-place idiom is used on reset(), the complete solution will look, following optional<>'s way: boost::optional<RAII_lock> lock; if ( cond ) lock.reset( in_place(entity) ); What do you think? Fernando Cacciola _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost