Troubles creating templated inout objects
Steven Schveighoffer
schveiguy at yahoo.com
Tue Jul 10 18:01:59 UTC 2018
On 7/10/18 10:34 AM, Timoses wrote:
> How do I create an inout object with template parameters?
>
> Take following code:
>
> import std.stdio;
> import std.traits;
>
> struct S
> {
> int[] arr;
> }
>
> interface I
> {
> inout(I) opIndex(size_t idx) inout;
> }
>
> class Test(T) : I
> {
> // Error: variable
> `onlineapp.Test!(inout(int)[]).Test.member` only parameters or stack
> based variables can be inout
> 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
> {
> switch (idx)
> static foreach (index, t; T.tupleof)
> {
> case index:
> // Error: template instance
> `onlineapp.Test!(inout(int)[])` error instantiating
> return new inout
> Test!(Unqual!(typeof(this.member.tupleof[index])))
> (this.member.tupleof[index]);
> default:
> return null;
> }
> }
> }
>
>
> unittest
> {
> auto s = S([1,2,3]);
> auto t = new const Test!S(s);
> }
>
>
> `Unqual` in this case just turns `inout(int[])` into `inout(int)[]`,
> which is why it complains. That's a side effect of this example, however
> the main question is how one would go about achieving something like
> this idiomatically?
>
> I would like to return a new object and that object should have the same
> mutability as the one creating it.
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.
-Steve
More information about the Digitalmars-d-learn
mailing list