Troubles creating templated inout objects

Steven Schveighoffer schveiguy at yahoo.com
Thu Jul 12 12:22:34 UTC 2018


On 7/11/18 8:55 AM, Timoses wrote:
> On Tuesday, 10 July 2018 at 18:01:59 UTC, Steven Schveighoffer wrote:
>> You are overthinking :) inout typically is much easier than you 
>> expect, until you need to create temporary structs or types with inout 
>> members, then it becomes problematic.
>>
>> https://run.dlang.io/is/kosYuC
>>
>> I had to put in a static if, because your function doesn't work once 
>> you get down to the array type. See the // fixme comment.
> 
> Ok, well that helped a tiny bit for the example.
> 
> I'm trying to reproduce the errors from my project. It's starting to get 
> out of control : D. inout is on a rampage!
> 
> https://run.dlang.io/is/5TN7XX
> 
> I guess it's the same as for immutable initialization of arrays. I can't 
> seem to find a proper response to this one..
> 
>      import std.traits;
> 
>      struct S
>      {
>          int[3] arr;
>      }
>      struct SS
>      {
>          S s;
>      }
> 
>      interface I
>      {
>          inout(I) opIndex(size_t idx) inout;
>      }
> 
>      class Test(T) : I
>      {
>          T member;
> 
>          this(inout T mem) inout
>          {
>              this.member = mem;
>          }
> 
>          inout(Test!T) get() inout
>          {
>              return new inout Test!(Unqual!(typeof(member)))(member);
>          }
> 
>          inout(I) opIndex(size_t idx) inout
>          {
>              static if (is(T == struct))
>              {
>                  switch (idx)
>                  static foreach (index, t; T.tupleof)
>                  {
>                      case index:
>                          return new inout
>                              
> Test!(Unqual!(typeof(this.member.tupleof[index])))
>                                          (this.member.tupleof[index]);
>                      default:
>                          return null;
>                  }
>              }
>              else
>                  return null;
>          }
>      }
> 
>      auto test(T)(inout T t)
>      {
>          return new inout Test!(Unqual!T)(t);
>      }
> 
>      class TestA(T : T[])
>      {
>          Test!T[] arr;
> 
>                  // ERROR: Can't initialize inout variable in a for loop...
>          this(inout(T[]) arr) inout
>          {
>              // 1: Nope
>              foreach (mem; arr)
>                  this.arr ~= test(mem);
> 
>              // 2: Nope
>              //Test!T[] a;
>              //foreach (mem; arr)
>              //   a ~= test(mem);
>

On the right track, but inside inout (or const or immutable) 
constructors, the members can only be initialized once. So you have to 
initialize a local, and then set the member once.

The issue is, your input is *also* inout (a necessary condition), so you 
didn't declare a properly:

inout(Test!T)[] a;
foreach (mem; arr) a ~= test(mem);
this.arr = a;

-Steve


More information about the Digitalmars-d-learn mailing list