On Fri, Dec 13, 2013 at 04:20:18PM +0100, Joseph Rushton Wakeling wrote:
> On 13/12/13 16:52, Marco Leise wrote:
> >Most non-trivial ranges do the actual work in `popFront()' and
> >return a cached value from `front'. It has been argued as a
> >design quirk, that this in general leads to:
> >
> >struct Range
> >{
> >   bool popFrontHasBeenCalledOnce = false;
> >   T current;
> >
> >   @property T front()
> >   {
> >     if (!popFrontHasBeenCalledOnce)
> >     {
> >       popFront();  // initializes `current'
> >     }
> >     return current;
> >   }
> >
> >   […]
> >}
> 
> For example in much of std.random.  With classes you can get round
> it by defining a default constructor, but with structs it can create
> some tricky situations.
> 
> I have wondered about the feasibility of a method called something
> like .first() which would basically be called the very first time
> one calls _any_ method of the struct/class in question, and would
> perform the appropriate initialization.

Hmm.

        struct First(T) /* bad name, I know */
                if (is(T.init.first()))
        {
                T impl;
                bool doneFirst;

                auto opDispatch(string funcName, A...)(A args)
                {
                        if (!doneFirst)
                        {
                                impl.first();
                                doneFirst = true;
                        }
                        alias func = mixin("impl." ~ func); // does this work?
                        return func(args);
                }
        }

        struct MyStructImpl
        {
                void first() { ... }
                void method() { ... }
        }

        alias MyStruct = First!MyStructImpl;

        MyStruct s;
        s.method();     // calls s.first() first.
        s.method();     // only calls method().


T

-- 
Жил-был король когда-то, при нём блоха жила.

Reply via email to