Ranges: is it ok if front is a data member?
H. S. Teoh
hsteoh at quickfur.ath.cx
Fri Dec 13 08:01:43 PST 2013
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
--
Жил-был король когда-то, при нём блоха жила.
More information about the Digitalmars-d-learn
mailing list