Thread overview
syntax for calling to with a getter as source argument
Jul 14, 2014
Klb
Jul 14, 2014
H. S. Teoh
Jul 15, 2014
Ali Çehreli
Jul 15, 2014
Ali Çehreli
Jul 15, 2014
Klb
July 14, 2014
hello what is the right syntax for this:

----------------------------------------------------
import std.stdio, std.conv;

void main(string args[])
{
    ubyte[3] src = [0, 1, 2];
    string trg = "";

    @property ubyte[3] srcAsProp(){return src;}

    // Error: template std.conv.to cannot deduce function from argument types
    // !(string)(ubyte[3]), candidates are:
    trg = to!(string)(srcAsProp());
}
----------------------------------------------------

In a real-world application I'd use an intermediate value but I'd like to know If it's possible...The strange fact is that it doesn't trig an error if src is a dyn. array. (if you remove the 3 from [3] then it passes).
July 14, 2014
On Mon, Jul 14, 2014 at 09:12:30PM +0000, Klb via Digitalmars-d-learn wrote:
> hello what is the right syntax for this:
> 
> ----------------------------------------------------
> import std.stdio, std.conv;
> 
> void main(string args[])
> {
>     ubyte[3] src = [0, 1, 2];
>     string trg = "";
> 
>     @property ubyte[3] srcAsProp(){return src;}
> 
>     // Error: template std.conv.to cannot deduce function from argument types
>     // !(string)(ubyte[3]), candidates are:
>     trg = to!(string)(srcAsProp());
> }
> ----------------------------------------------------
> 
> In a real-world application I'd use an intermediate value but I'd like to know If it's possible...The strange fact is that it doesn't trig an error if src is a dyn. array. (if you remove the 3 from [3] then it passes).

You need to slice the static array:

	trg = to!string(srcAsProp()[]);

Or, if you like to use UFCS (Uniform Function Call Syntax):

	trg = srcAsProp()[].to!string;

You might want to file an enhancement request to improve the error message, though -- it's not very helpful as it stands.


T

-- 
Trying to define yourself is like trying to bite your own teeth. -- Alan Watts
July 15, 2014
On 07/14/2014 04:04 PM, H. S. Teoh via Digitalmars-d-learn wrote:

> On Mon, Jul 14, 2014 at 09:12:30PM +0000, Klb via Digitalmars-d-learn wrote:
>> hello what is the right syntax for this:
>>
>> ----------------------------------------------------
>> import std.stdio, std.conv;
>>
>> void main(string args[])
>> {
>>      ubyte[3] src = [0, 1, 2];
>>      string trg = "";
>>
>>      @property ubyte[3] srcAsProp(){return src;}
>>
>>      // Error: template std.conv.to cannot deduce function from argument types
>>      // !(string)(ubyte[3]), candidates are:
>>      trg = to!(string)(srcAsProp());
>> }
>> ----------------------------------------------------
>>
>> In a real-world application I'd use an intermediate value but I'd like
>> to know If it's possible...The strange fact is that it doesn't trig an
>> error if src is a dyn. array. (if you remove the 3 from [3] then it
>> passes).
>
> You need to slice the static array:
>
> 	trg = to!string(srcAsProp()[]);

There seems to be an attempt in Phobos to support it without needing an explicit slice.

From std/phobos/conv.d:

/*
  Converting static arrays forwards to their dynamic counterparts.
 */
T toImpl(T, S)(ref S s)
    if (isRawStaticArray!S)
{
    return toImpl!(T, typeof(s[0])[])(s);
}

@safe pure nothrow unittest
{
    char[4] test = ['a', 'b', 'c', 'd'];
    static assert(!isInputRange!(Unqual!(char[4])));
    assert(to!string(test) == test);
}

I don't know why that overload does not take care of OP's case. (I am be completely off here. :) )

Ali

July 15, 2014
On 07/14/2014 05:10 PM, Ali Çehreli wrote:

> On 07/14/2014 04:04 PM, H. S. Teoh via Digitalmars-d-learn wrote:
>
>  > On Mon, Jul 14, 2014 at 09:12:30PM +0000, Klb via Digitalmars-d-learn
> wrote:
>  >> hello what is the right syntax for this:
>  >>
>  >> ----------------------------------------------------
>  >> import std.stdio, std.conv;
>  >>
>  >> void main(string args[])
>  >> {
>  >>      ubyte[3] src = [0, 1, 2];
>  >>      string trg = "";
>  >>
>  >>      @property ubyte[3] srcAsProp(){return src;}
>  >>
>  >>      // Error: template std.conv.to cannot deduce function from
> argument types
>  >>      // !(string)(ubyte[3]), candidates are:
>  >>      trg = to!(string)(srcAsProp());
>  >> }
>  >> ----------------------------------------------------
>  >>
>  >> In a real-world application I'd use an intermediate value but I'd like
>  >> to know If it's possible...The strange fact is that it doesn't trig an
>  >> error if src is a dyn. array. (if you remove the 3 from [3] then it
>  >> passes).
>  >
>  > You need to slice the static array:
>  >
>  >     trg = to!string(srcAsProp()[]);
>
> There seems to be an attempt in Phobos to support it without needing an
> explicit slice.
>
>  From std/phobos/conv.d:

I meant phobos/std/conv.d there.

> /*
>    Converting static arrays forwards to their dynamic counterparts.
>   */
> T toImpl(T, S)(ref S s)
>      if (isRawStaticArray!S)

Ok, I think I see now (after two minutes after posting it :) ) why it doesn't work. The overload above takes by-ref, which does not bind to rvalues in D.

And the problem is, what srcAsProp() returns is an rvalue because static arrays are value-types and they get copied.

> {
>      return toImpl!(T, typeof(s[0])[])(s);
> }
>
> @safe pure nothrow unittest
> {
>      char[4] test = ['a', 'b', 'c', 'd'];
>      static assert(!isInputRange!(Unqual!(char[4])));
>      assert(to!string(test) == test);
> }
>
> I don't know why that overload does not take care of OP's case. (I am be
> completely off here. :) )

I hope I have it now. :p

Ali

July 15, 2014
On Tuesday, 15 July 2014 at 00:19:15 UTC, Ali Çehreli wrote:
> On 07/14/2014 05:10 PM, Ali Çehreli wrote:
>
> > On 07/14/2014 04:04 PM, H. S. Teoh via Digitalmars-d-learn
> wrote:
> >
> >  > On Mon, Jul 14, 2014 at 09:12:30PM +0000, Klb via
> Digitalmars-d-learn
> > wrote:
> >  >> hello what is the right syntax for this:
> >  >>
> >  >> ----------------------------------------------------
> >  >> import std.stdio, std.conv;
> >  >>
> >  >> void main(string args[])
> >  >> {
> >  >>      ubyte[3] src = [0, 1, 2];
> >  >>      string trg = "";
> >  >>
> >  >>      @property ubyte[3] srcAsProp(){return src;}
> >  >>
> >  >>      // Error: template std.conv.to cannot deduce
> function from
> > argument types
> >  >>      // !(string)(ubyte[3]), candidates are:
> >  >>      trg = to!(string)(srcAsProp());
> >  >> }
> >  >> ----------------------------------------------------
> >  >>
> >  >> In a real-world application I'd use an intermediate value
> but I'd like
> >  >> to know If it's possible...The strange fact is that it
> doesn't trig an
> >  >> error if src is a dyn. array. (if you remove the 3 from
> [3] then it
> >  >> passes).
> >  >
> >  > You need to slice the static array:
> >  >
> >  >     trg = to!string(srcAsProp()[]);
> >
> > There seems to be an attempt in Phobos to support it without
> needing an
> > explicit slice.
> >
> >  From std/phobos/conv.d:
>
> I meant phobos/std/conv.d there.
>
> > /*
> >    Converting static arrays forwards to their dynamic
> counterparts.
> >   */
> > T toImpl(T, S)(ref S s)
> >      if (isRawStaticArray!S)
>
> Ok, I think I see now (after two minutes after posting it :) ) why it doesn't work. The overload above takes by-ref, which does not bind to rvalues in D.
>
> And the problem is, what srcAsProp() returns is an rvalue because static arrays are value-types and they get copied.
>
> > {
> >      return toImpl!(T, typeof(s[0])[])(s);
> > }
> >
> > @safe pure nothrow unittest
> > {
> >      char[4] test = ['a', 'b', 'c', 'd'];
> >      static assert(!isInputRange!(Unqual!(char[4])));
> >      assert(to!string(test) == test);
> > }
> >
> > I don't know why that overload does not take care of OP's
> case. (I am be
> > completely off here. :) )
>
> I hope I have it now. :p
>
> Ali

Thanks for this accurate explanation. The problem is quite clear now.