auto & class members

Jonathan M Davis newsgroup.d at jmdavisprog.com
Mon May 21 19:30:15 UTC 2018


On Monday, May 21, 2018 11:13:16 Ali Çehreli via Digitalmars-d-learn wrote:
> On 05/20/2018 10:46 AM, Robert M. Münch wrote:
>  > But I still don't understand why I can't write things explicitly but
>  > have to use an alias for this.
>
> Templatized range types work well when they are used as template
> arguments themselves.
>
> When you need to keep a single type like 'b' (i.e. b is not a template),
> and when you need to set a variable like mySubStream to a dynamic
> object, the solution is to use inputObject():
>
> import std.algorithm;
> import std.range;
>
> class a {
>      int[] myStream = [ 1, 2, 42, 100 ];
> }
>
>
> int myMessage = 42;
>
> class b {
>      InputRange!int mySubStream;
> }
>
> void myFunc() {
>      a myA = new a();
>      b myB = new b();
>
>      myB.mySubStream = inputRangeObject(myA.myStream.filter!(x => x ==
> myMessage));
>
>      assert(myB.mySubStream.equal([myMessage]));
> }
>
> void main() {
>      myFunc();
> }
>
> Now, mySubStream is a range variable that satisfies the input range
> interface and produces int elements. (Adjust accordingly.) You can use a
> more specialized range kind other than InputRange if the actual range
> supports it (e.g. ForwardRange!int, etc.):
>
>
> http://ddili.org/ders/d.en/ranges_more.html#ix_ranges_more.inputRangeObjec
> t
>
>    https://dlang.org/phobos/std_range_interfaces.html#inputRangeObject

Wow. Someone actually uses those? I don't think that I've ever seen anyone
try except when they didn't understand ranges properly and thought that all
ranges derived from the interfaces in that module. I guess that they would
work in this case, but I think that the normal solution is to use typeof
(though as Robert here found, that can get a bit problematic when lambdas
get involved, whereas your solution here is pretty straightforward).

I'd be _very_ leery of using ForwardRange and the like though, since they're
going to have to allocate on every call to save, which gets expensive, and
far too often, range-based code doesn't call save correctly, meaning that
you'll often hit bugs using a forward range that's a class. Phobos is a
_lot_ better about it than it used to be, but I expect that there are still
a few such lingering bugs in there, and I'd expect the average range-based
code to screw it up. Really, the only way to get it right is to actually
test your code with reference type ranges.

If all you're using is a basic input range, then those interfaces just cost
you the one allocation and should be fine, but beyond that, I wouldn't
suggest using them if you can reasonably avoid it. And personally, I'd just
use Steven's solution of using a wrapper function so that you can ensure
that there's really only one lambda type involved, and typeof then works.

- Jonathan M Davis




More information about the Digitalmars-d-learn mailing list