inout in opAssert in custom range

Valentino Giudice valentino.giudice96 at gmail.com
Sun Aug 30 03:28:49 UTC 2026


Consider the following example:

module demo1;

```D
class MyClass
{
     int a;

     this(int a)
     {
         this.a = a;
     }
}

struct MyRange
{
     MyClass[] _items;

     this(MyClass[] items)
     {
         this._items = items;
     }

     int opApply(scope int delegate(inout MyClass item) dg) inout
     {
         for (size_t i = 0; i < this._items.length; i++)
         {
             int result = dg(this._items[i]);
             if (result != 0)
             {
                 return result;
             }
         }
         return 0;
     }

     inout(MyClass) opIndex(size_t i) inout nothrow
     {
         return this._items[i];
     }

     size_t length() const nothrow
     {
         return this._items.length;
     }

     public alias opDollar = length;
}

void main()
{
     MyClass[2] items;
     items[0] = new MyClass(1);
     items[1] = new MyClass(2);

     MyRange r = MyRange(items);

     foreach (MyClass item; r)
     {
         // Operations
     }

     const MyRange r2 = MyRange(items);

     foreach (const MyClass item; r2)
     {
         // Operations
     }
}
```

The idea is that when the range is constant looping should yield 
constant objects and when it's mutable it should yield mutable 
objects.

The code above leads to the following error:

```
Error: cannot uniquely infer `foreach` argument types
     foreach (MyClass item; r)
Error: cannot uniquely infer `foreach` argument types
     foreach (const MyClass item; r2)
```

This problem does not occur if I replace the `inout` declaration 
of `opApply` with the following:

```D
int opApply(scope int delegate(MyClass item) dg)
{
     for (size_t i = 0; i < this._items.length; i++)
     {
         int result = dg(this._items[i]);
         if (result != 0)
         {
             return result;
         }
     }
     return 0;
}

int opApply(scope int delegate(const MyClass item) dg) const
{
     for (size_t i = 0; i < this._items.length; i++)
     {
         int result = dg(this._items[i]);
         if (result != 0)
         {
             return result;
         }
     }
     return 0;
}
```

This is obviously suboptimal and requires duplication of code.

Is there a way to obtain the desired effect without duplicating 
code?

Thank you a lot in advance!


More information about the Digitalmars-d-learn mailing list