Thread overview
using parse with string slice
Dec 05, 2015
Quentin Ladeveze
Dec 05, 2015
anonymous
Dec 05, 2015
Quentin Ladeveze
Dec 05, 2015
Adam D. Ruppe
December 05, 2015
Hi,

I try to parse some hexadecimal numbers stocked in a string. So I use this code


---
import std.conv;

string s = "B";

int value = parse!int(s, 16);

assert(value == 11);
---

But when I have several hexadecimal numbers in the string, and I slice it, the compiler can't deduce which version of parse to use :

---
import std.conv;

string s = "1B2A";

int value = parse!int(s[0..2], 16); //template std.conv.parse cannot deduce function from argument types !(int)(string, int)
---

Does someone have an idea of why it happens ? The version of parse that is used here is :

---
std.conv.parse(Target, Source)(ref Source s, uint radix) if (isSomeChar!(ElementType!Source) && isIntegral!Target && !is(Target == enum))
---

And I can't see which template constraint is not respected when I call it with a slice.

Thanks
December 05, 2015
On 05.12.2015 22:59, Quentin Ladeveze wrote:
> ---
> import std.conv;
>
> string s = "1B2A";
>
> int value = parse!int(s[0..2], 16); //template std.conv.parse cannot
> deduce function from argument types !(int)(string, int)
> ---
>
> Does someone have an idea of why it happens ? The version of parse that
> is used here is :
>
> ---
> std.conv.parse(Target, Source)(ref Source s, uint radix) if
> (isSomeChar!(ElementType!Source) && isIntegral!Target && !is(Target ==
> enum))
> ---
>
> And I can't see which template constraint is not respected when I call
> it with a slice.

It's the `ref` part. A slice expression cannot be passed in a ref parameter. You can use std.conv.to instead or assign the slice to a variable first.
December 05, 2015
On Saturday, 5 December 2015 at 22:05:11 UTC, anonymous wrote:
> On 05.12.2015 22:59, Quentin Ladeveze wrote:
>> ---
>> import std.conv;
>>
>> string s = "1B2A";
>>
>> int value = parse!int(s[0..2], 16); //template std.conv.parse cannot
>> deduce function from argument types !(int)(string, int)
>> ---
>>
>> Does someone have an idea of why it happens ? The version of parse that
>> is used here is :
>>
>> ---
>> std.conv.parse(Target, Source)(ref Source s, uint radix) if
>> (isSomeChar!(ElementType!Source) && isIntegral!Target && !is(Target ==
>> enum))
>> ---
>>
>> And I can't see which template constraint is not respected when I call
>> it with a slice.
>
> It's the `ref` part. A slice expression cannot be passed in a ref parameter. You can use std.conv.to instead or assign the slice to a variable first.

Thank you for your quick answer, learned something today :)
December 05, 2015
On Saturday, 5 December 2015 at 22:05:11 UTC, anonymous wrote:
> You can use std.conv.to instead or assign the slice to a variable first.

This is a bit of a FAQ I think because people don't realize you can use to and parse to do the same thing.

The big difference is parse will advance the slice you pass it past the item it reads, whereas to will try to convert the entire input.

That's why parse wants a ref slice, so it can move it forward. But since you're slicing it yourself, to is the way to go.