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