www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Iterators in structs

reply repr-man <jxl.ppg gmail.com> writes:
As an extension of my previous thread 
(https://forum.dlang.org/thread/nupwljahyutnyxdvpxob forum.dlang.org), I wanted
to ask about iterators in structs.  I will start with the following code:

void main()
{
     int[5] a = [0, 1, 2, 3, 4];
     int[5] b = [5, 6, 7, 8, 9];

     auto x = ChunksOf(chain(a[], b[]), 2);
}

struct ChunksOf
{
     this(R)(R r, size_t width)
     {
         auto iter = r.chunks(width);
         assert(is(typeof(iter) == Chunks!R));
     }
}

This code works as expected.  However, if the struct changes to:

struct ChunksOf
{
     Chunks!R iter;

     this(R)(R r, size_t width)
     {
         this.iter = r.chunks(width);
         assert(is(typeof(iter) == Chunks!R));
     }
}

it doesn't compile because R is only in the scope of the 
constructor.  This leads me to change the struct to:

struct ChunksOf(R)
{
     Chunks!R iter;

     this(R r, size_t width)
     {
         this.iter = r.chunks(width);
         assert(is(typeof(iter) == Chunks!R));
     }
}

This works, only if I change the declaration of x in main() to:

     auto x = ChunksOf!(chain(a[], b[]))(chain(a[], b[]), 2);

This requires me to pass the iterator as a template parameter and 
a regular parameter.  Since this is a bit redundant, and I wanted 
to know if there was a better way to do it.

Thanks for the help!
Jun 25 2020
parent Paul Backus <snarwin gmail.com> writes:
On Thursday, 25 June 2020 at 18:47:42 UTC, repr-man wrote:
 struct ChunksOf(R)
 {
     Chunks!R iter;

     this(R r, size_t width)
     {
         this.iter = r.chunks(width);
         assert(is(typeof(iter) == Chunks!R));
     }
 }

 This works, only if I change the declaration of x in main() to:

     auto x = ChunksOf!(chain(a[], b[]))(chain(a[], b[]), 2);

 This requires me to pass the iterator as a template parameter 
 and a regular parameter.  Since this is a bit redundant, and I 
 wanted to know if there was a better way to do it.

 Thanks for the help!
The usual solution is to create a helper function: ChunksOf!R chunksOf(R)(R r, size_t width) { return ChunksOf!R(r, width); } The compiler can infer template arguments for function calls, so you can call it like this: auto x = chunksOf(chain(a[], b[]), 2);
Jun 25 2020