On Tuesday, July 10, 2012 18:57:25 Jacob Carlborg wrote: > On 2012-07-10 16:36, Dmitry Olshansky wrote: > > typeof to the rescue. In fact I'm not so proud of voldemort types. As > > when you need to sotre range somewhere they stand in your way for no > > benefit. > > I'm not exactly sure how you mean but this is what I came up with: > > import std.algorithm; > import std.traits; > import std.conv; > > class Foo > { > auto bar () > { > return [3, 4].map!(x => x.to!(string)); > } > > ReturnType!(bar) x; > }
typeof(bar()) x; works. But regardless, given that you're dealing with a return type which is auto, there's really no other choice. Even if we weren't using voldemort types for stuff like map, the return type would still be templated and depend on the actual arguments to map, making writing the type a pain - especially if it's complicated; until (which _doesn't_ use a voldemort type) is a prime example of this. You end up with something like Until!("a == b",int[],int) for a basic call to until, and it gets really nasty if you start chaining function calls so that the range passed to Until is far more complicated than int[]. Using ReturnType and typeof becames the sane thing to do (and much more maintainable too, since you don't have to change it if/when you change the call to map enough that it's return type changes). It does take some getting used to, but it works very well. You just have to realize that if you're operating on ranges, you're generally _not_ caring what they exact type is, and you use auto and templates a lot. Sometimes converting the result to an array is exactly what you want to do, but the less you do that, the more efficient your code will be. - Jonathan M Davis