On Sun, Aug 31, 2003 at 12:34:39AM -0700, Mat Marcus wrote: > In this post I will put forward a use-case or two to help see whether > something a little different then the current version of optional > might be useful. I also begin making a case that a Concept like > PossiblyUninitializedVariable might be more generally useful than > OptionalPointee. As I mentioned in the post that started this thread, ... > std::pair<Iter, Iter> out_edges(Vertex, Graph); > boost::optional<Iter> begin, end; //now use optional > Graph g(/*...*/); > boost::tie(begin, end) = out_edges(v,g); //sorry, doesn't work > boost::tie(*begin, *end); //sorry, ASSERT && looks too strange ...
First off, let me say I do think this is a compelling use-case. (As an aside, this is exactly why people in functional languages love pattern-matching; it's a general facility for deconstructing data into its constituents, where each portion is a new, named variable.) I missed the beginning of this thread, but I imagine the motivation is to avoid having to say std::pair<Iter,Iter> p = out_edges(v,g); Iter begin = p.first; Iter end = p.second; each and every single time you call out_edges(). As I think someone else in the thread mentioned, there has to be some explicit call to turn an "optional<T>" into a "T", or else the two interfaces get muddled together. The same would be true of PossiblyUninitializedVariable. You've also mentioned that you think operator*() is inapproprate/ugly for this use. So, here's an idea for something completely new which maybe helps fit your requirements. I start with the motivating example: PossUninitVar<Iter> begin, end; tie( +begin, +end ) = out_edges(v,g); for( Iter i = ~begin; i != ~end; ++i ) ... (Effectively operator~() fetches the value (or asserts if there is none), whereas operator+() returns a reference to the yet-nonexistent value so it can be filled in by someone else.) Now here's a (sloppy, partial) summary of the interface, along with some of the implementation: template <class T> struct PossUninitVar { PossUninitVar() : init(false) {} PossUninitVar( const T& x ) : init(true) { new (raw_storage) T(x); } operator bool() { return init; } Proxy operator +() { return unsafe_get(); } T& operator~() { return get(); } private: bool init; Something raw_storage; // array of bytes with right size/alignment T& get() { if(!init) assert; else /* returns T& from raw storage */ } Proxy unsafe_get() { return Proxy(this); } class Proxy { PossUninitVar* puv; public: T& operator=( const T& x ) { new (puv->raw_storage) T(x); puv->init = true; return puv->get(); } }; }; Hopefully you get the idea. I think this meets your wish list. Making tie() interact properly with the Proxy might be hard. Just some ideas; refine, reject, whatever, as you please... -- -Brian McNamara ([EMAIL PROTECTED]) _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost