splitter, compilation issue

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Oct 27 14:54:21 PDT 2015


On Tuesday, October 27, 2015 20:58:56 sigod via Digitalmars-d-learn wrote:
> Here's simple code:
>
>   import std.algorithm;
>   import std.array;
>   import std.file;
>
>   void main(string[] args)
>   {
>       auto t = args[1].readText()
>           .splitter('\n')
>           .filter!(e => e.length)
>           .split("---")
>       ;
>   }
>
> Looks like it should work, but it won't compile. DMD 2.068.2
> fails with this error:
>
>   Error: template std.algorithm.iteration.splitter cannot deduce
> function from argument types !()(FilterResult!(__lambda2,
> Result), string), candidates are:
>   ...
>   Error: template instance
> std.array.split!(FilterResult!(__lambda2, Result), string) error
> instantiating
>
> It compiles if I insert `.array` before `.split(...`.
>
> Am I missing something? Or it's a bug? I've tried to make a brief
> search in the bug tracker, but didn't found anything.
>
> P.S. dpaste gives very strange error:
>
>   /d712/f815.d(8): Error: unterminated character constant
>   /d712/f815.d(9): Error: unterminated character constant
>   ... and so on

Well, split calls splitter, and it doesn't make much of an attempt to check
its arguments in its template constraint, mostly passing the buck onto
splitter, since it's really just a wrapper around splitter that calls array
on the result. You could actually reduce your code down to something more
like

auto t = "hello".filter!"true"().splitter(" ");

and you'd have the same problem. And looking at splitter's template
constraint, it requires either a narrow string (which the result of filter
is not) or a range for which hasSlicing is true (which is not the case for
the result of filter). Whether splitter could be implemented without that
(e.g. returning a range of Take), I don't know, but it's pretty clear that
the current implementation requires slicing, and if you're using filter,
that means that you'd need to do something like use array to convert it to a
range which _can_ be sliced to pass to split or splitter.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list