digitalmars.D.learn - Inference of auto storage classes for interface function return type
- Timoses (42/42) Jul 04 2018 How can I return inferred storage class from interface functions?
- Nicholas Wilson (6/49) Jul 04 2018 IIRC to apply inout to the this pointer:
- Jonathan M Davis (4/46) Jul 04 2018 You can make opIndex inout instead of const. That way, inout applies to ...
How can I return inferred storage class from interface functions? I can't use auto as return value in interface. Neither can I use "inout" as I don't pass a parameter. // Ref Type interface IRef { Ref opIndex(size_t idx) const; } class CRef : IRef { Ref[] a; this() immutable { this.a = [new Ref()]; } Ref opIndex(size_t idx) const { return a[idx]; } // Error: cannot implicitly convert expression this.a[idx] of type const(Ref) to app.Ref } class Ref{} void main() { auto a = new immutable(CRef)(); auto s = a[3]; } For value types it works, I presume since they are passed by value, so the instance returned is an actual copy of the stored value. // Value Type interface IValue { Value opIndex(size_t idx) const; } class CValue : IValue { this() immutable { i = [Value()]; } Value[] i; Value opIndex(size_t idx) const { return i[idx]; } } struct Value{} However, for ref types this doesn't work. Do I have to define two `opIndex` in the interface? One mutable, one for immutable type instances?
Jul 04 2018
On Wednesday, 4 July 2018 at 14:07:35 UTC, Timoses wrote:How can I return inferred storage class from interface functions? I can't use auto as return value in interface. Neither can I use "inout" as I don't pass a parameter. // Ref Type interface IRef { Ref opIndex(size_t idx) const; } class CRef : IRef { Ref[] a; this() immutable { this.a = [new Ref()]; } Ref opIndex(size_t idx) const { return a[idx]; } // Error: cannot implicitly convert expression this.a[idx] of type const(Ref) to app.Ref } class Ref{} void main() { auto a = new immutable(CRef)(); auto s = a[3]; } For value types it works, I presume since they are passed by value, so the instance returned is an actual copy of the stored value. // Value Type interface IValue { Value opIndex(size_t idx) const; } class CValue : IValue { this() immutable { i = [Value()]; } Value[] i; Value opIndex(size_t idx) const { return i[idx]; } } struct Value{} However, for ref types this doesn't work. Do I have to define two `opIndex` in the interface? One mutable, one for immutable type instances?IIRC to apply inout to the this pointer: Ref opIndex(size_t idx) inout; or inout(Ref) opIndex(size_t idx) inout; not sure off the top of my head,
Jul 04 2018
On Wednesday, July 04, 2018 14:07:35 Timoses via Digitalmars-d-learn wrote:How can I return inferred storage class from interface functions? I can't use auto as return value in interface. Neither can I use "inout" as I don't pass a parameter. // Ref Type interface IRef { Ref opIndex(size_t idx) const; } class CRef : IRef { Ref[] a; this() immutable { this.a = [new Ref()]; } Ref opIndex(size_t idx) const { return a[idx]; } // Error: cannot implicitly convert expression this.a[idx] of type const(Ref) to app.Ref } class Ref{} void main() { auto a = new immutable(CRef)(); auto s = a[3]; } For value types it works, I presume since they are passed by value, so the instance returned is an actual copy of the stored value. // Value Type interface IValue { Value opIndex(size_t idx) const; } class CValue : IValue { this() immutable { i = [Value()]; } Value[] i; Value opIndex(size_t idx) const { return i[idx]; } } struct Value{} However, for ref types this doesn't work. Do I have to define two `opIndex` in the interface? One mutable, one for immutable type instances?You can make opIndex inout instead of const. That way, inout applies to the invisible this reference, just like it would with const. - Jonathan M Davis
Jul 04 2018
On Wednesday, 4 July 2018 at 15:12:15 UTC, Jonathan M Davis wrote:You can make opIndex inout instead of const. That way, inout applies to the invisible this reference, just like it would with const.Awww, thanks! I was kinda hovering around this[1] section and didn't quite see the MemberFunctionAttribute list[2]. Is there no further description of the behaviour with the inout attribute other than for parameters[1] in the spec? There's an empty 19.10.10 point without content[3] : D. Maybe a placeholder? [1]: https://dlang.org/spec/function.html#inout-functions [2]: https://dlang.org/spec/function.html#MemberFunctionAttribute [3]: https://dlang.org/spec/function.html#inout-functions
Jul 04 2018
On 07/04/2018 05:59 PM, Timoses wrote:There's an empty 19.10.10 point without content[3] : D. Maybe a placeholder?[...][3]: https://dlang.org/spec/function.html#inout-functionsJust a bug. https://github.com/dlang/dlang.org/pull/2407
Jul 04 2018