On 3/23/16 6:25 PM, Ali Çehreli wrote:
On 03/23/2016 02:31 PM, cy wrote:

 > struct Someop(Type) {
 >    Type thing;
 >    void foo() {
 >      thing.bar();
 >    }
 > }
 >
 > struct Foo {
 >    void bar() {
 >      import std.stdio: writeln;
 >      writeln("bar");
 >    }
 > }
 >
 > struct Bar {
 >    void thingy(inout(Foo) foo) inout {
 >      auto op = Someop(foo);

The following is a workaround for this example:

       auto op = Someop!Foo(foo);

I would be surprised if the original code worked regardless of inout status. Struct implicit ctors are not IFTI-compatible.

Note what is happening here in your update is likely not what the OP expects. Since Foo contains no indirections, it is a value type. So it can be implicitly cast from inout to mutable (same thing with Someop). As soon as you involve a pointer here, it would stop compiling.


I'm not sure whether Someop's implicit constructor should take part in
deducing Someop's Type template parameter.

There is no deduction.

However, you can specify that you are explicitly constructing an inout Someop:

auto op = inout(Someop!Foo)(foo);

However, this will not allow Bar to compile, since it calls op.foo, and Someop.foo is not inout, neither is Foo.bar, so neither can be called.

In this case, you need to mark Foo.bar and Someop.foo as inout. Marking Foo.bar as inout is probably acceptable, but marking Someop.foo as inout is tricky, since it's a wrapper, and can't predict what Type is going to allow.

This is one of the viral situations that frankly affects all the mutability modifiers.

-Steve

Reply via email to