Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
July 04, 2018 Inference of auto storage classes for interface function return type | ||||
---|---|---|---|---|
| ||||
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? |
July 04, 2018 Re: Inference of auto storage classes for interface function return type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timoses | 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,
|
July 04, 2018 Re: Inference of auto storage classes for interface function return type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timoses | 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
|
July 04, 2018 Re: Inference of auto storage classes for interface function return type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | 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 |
July 04, 2018 Re: Inference of auto storage classes for interface function return type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timoses | 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-functions Just a bug. https://github.com/dlang/dlang.org/pull/2407 |
Copyright © 1999-2021 by the D Language Foundation