Using decodeFront with a generalised input range

Dennis dkorpel at gmail.com
Fri Nov 9 10:26:46 UTC 2018


On Friday, 9 November 2018 at 09:47:32 UTC, Vinay Sajip wrote:
> std.utf.decodeFront(Flag useReplacementDchar = 
> No.useReplacementDchar, S)(ref S str) if (isInputRange!S && 
> isSomeChar!(ElementType!S))

This is the overload you want, let's check if it matches:
ref S str - your InputRange can be passed by reference, but you 
specified S = dchar. S here is the type of the inputRange, and it 
is not of type dchar. It's best not to specify S so the compiler 
will infer it, range types can be very complicated. Once we fix 
that, let's look at the rest:

isInputRange!S - S is an inputRange
isSomeChar!(ElementType!S) - ElementType!S is ubyte, but 
isSomeChar!ubyte is not true.

The function wants characters, but you give bytes. A quick fix 
would be to do:
```
import std.algorithm: map;
auto mapped = r.map!(x => cast(char) x);
mapped.decodeFront!(No.useReplacementDchar)();
```

But it may be better for somefn to accept an InputRange!(char) 
instead.

Note that if you directly do:
```
r.map!(x => cast(char) x).decodeFront!(No.useReplacementDchar)();
```
It still won't work, since it wants `ref S str` and r.map!(...) 
is a temporary that can't be passed by reference.

As you can see, ensuring template constraints can be really 
difficult. The error messages give little help here, so you have 
to manually check whether the conditions of the overload you want 
hold.


More information about the Digitalmars-d-learn mailing list