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