|
Boost : |
From: Mat Marcus (mmarcus-boost_at_[hidden])
Date: 2003-08-31 12:41:15
--On Sunday, August 31, 2003 10:29 AM -0400 Brian McNamara
<lorgon_at_[hidden]> wrote:
> 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().
IIUC, you are saying that you don't find the use of tie with pairs
very compelling. Fair enough. Of course tie is more generically useful
with arbitrary tuples and multi-value returns. I was just trying to
present a small familiar example of such usage.
>
>
> 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.
In general I'm not a fan of implicit conversions or constructors.
However one of my goals is to be able to easily/readably move code
from using raw variables to use PossiblyUnitinitializedVariables
instead. So..
> 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.)
... here I like the + or something like it
begin.reference_to_uninitialized(). That is I don't mind when users
have to be a little more explicit in the dangerous/uncommon case. ~ is
also interesting, although I think that readability suffers. I'd give
up bool conversion and operator! to avoid the need for ~ if that would
reasonably solve the muddling issues. But perhaps there would be too
many other problems -- I haven't explored this deeply yet.
> 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 (lorgon_at_[hidden])
Thanks for the ideas, and for your functional programming explanations.
- Mat
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk