www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Struct initialization, implicit conversions and delegates

reply Nicolas Silva <nical.silva gmail.com> writes:
--0023544703441affc004b6aa98d5
Content-Type: text/plain; charset=ISO-8859-1

Hi,

I have two syntactic "difficulties" when initializing structs:

1)
Say I have a struct StringHash that represents the hash code of a string.

struct StringHash
{
    this( string str )
    {
        computeHash(str);
    }

    void computeHash( string str )
    {
        hash = 0;
        foreach(c;str)
        {
            hash ^= c;
            hash *= 0x93;
        }
    }

    bool opEquals( ref const(StringHash) s )
    {
        return hash == s.hash;
    }

    bool opEquals( string s )
    {
        return hash == StringHash(s).hash;
    }

    uint hash;
}

I would like this structure to be as transparent as possible and be able to
write things like:

StringHash sh = "SomeString"; // ok

struct Foo
{
    StringHash name;
}

Foo foo = {
   name : "SomeString" //  Error: cannot implicitly convert expression
("SomeString") of type string to StringHash
   category : HString( "SomeString" ); // works, but looks less nice IMO.
};


2)
It looks like I can't initialize fields of a struct with anonymous
functions or delegates (the error is not clear to me though), for example:

struct Element
{
   void delegate(void) onSomething;
   void delegate(void) onSomethingElse;
}

void main()
{
    auto callBack = delegate void(void) { stdout.writeln("callBack"); };

    Element e = {
        onSomething : callBack, // ok
        onSomethingElse : delegate void(void) {
stdout.writeln("anonymous"); } // errors (this is line 15, see below)
    };
}

test.d(15): found ':' when expecting ';' following statement
test.d(16): found '}' when expecting ';' following statement
test.d(19): semicolon expected, not 'EOF'
test.d(19): found 'EOF' when expecting '}' following compound statement


Both of these little problems are not crucial, but they could bring some
very nice syntactic sugar on the API I am designing right now.
how should I fix it?
If the actual behaviors are desired i'd be interested to know the arguments
(well, i can imagine motivation for explicit conversion, but for the
delegate thing it's less clear to me).

Thanks,

Nicolas

--0023544703441affc004b6aa98d5
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Hi,<br><br>I have two syntactic &quot;difficulties&quot; when initializing =
structs:<br><br>1)<br>Say I have a struct StringHash that represents the ha=
sh code of a string.<br><br>struct StringHash<br>{<br>=A0=A0=A0 this( strin=
g str )<br>

=A0=A0=A0 {<br>=A0=A0=A0=A0=A0=A0=A0 computeHash(str);<br>=A0=A0=A0 }<br><b=
r>=A0=A0=A0 void computeHash( string str )<br>=A0=A0=A0 {<br>=A0=A0=A0=A0=
=A0=A0=A0 hash =3D 0;<br>=A0=A0=A0=A0=A0=A0=A0 foreach(c;str)<br>=A0=A0=A0=
=A0=A0=A0=A0 {<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 hash ^=3D c;<br>=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0 hash *=3D 0x93;<br>=A0=A0=A0=A0=A0=A0=A0 }<br>

=A0=A0=A0 }<br>=A0=A0=A0 <br>=A0=A0=A0 bool opEquals( ref const(StringHash)=
 s )<br>=A0=A0=A0 {<br>=A0=A0=A0=A0=A0=A0=A0 return hash =3D=3D s.hash;<br>=
=A0=A0=A0 }<br>=A0=A0=A0 <br>=A0=A0=A0 bool opEquals( string s )<br>=A0=A0=
=A0 {<br>=A0=A0=A0=A0=A0=A0=A0 return hash =3D=3D StringHash(s).hash;<br>=
=A0=A0=A0 }<br>

<br>=A0=A0=A0 uint hash;<br>}<br><br>I would like this structure to be as t=
ransparent as possible and be able to write things like:<br><br>StringHash =
sh =3D &quot;SomeString&quot;; // ok<br><br>struct Foo<br>{<br>=A0=A0=A0 St=
ringHash name;<br>

}<br><br>Foo foo =3D {<br>=A0=A0 name : &quot;SomeString&quot; //=A0 Error:=
 cannot implicitly convert expression (&quot;SomeString&quot;) of type stri=
ng to StringHash<br>=A0=A0 category : HString( &quot;SomeString&quot; ); //=
 works, but looks less nice IMO.<br>

};<br><br><br>2)<br>It looks like I can&#39;t initialize fields of a struct=
 with anonymous functions or delegates (the error is not clear to me though=
), for example:<br><br>struct Element<br>{<br>=A0=A0 void delegate(void) on=
Something;<br>

=A0=A0 void delegate(void) onSomethingElse;<br>}<br><br>void main()<br>{<br=
=A0=A0=A0 auto callBack =3D delegate void(void) { stdout.writeln(&quot;cal=

onSomething : callBack, // ok<br> =A0=A0=A0=A0=A0=A0=A0 onSomethingElse : delegate void(void) { stdout.writel= n(&quot;anonymous&quot;); } // errors (this is line 15, see below)<br>=A0= =A0=A0 };<br>}<br><br>test.d(15): found &#39;:&#39; when expecting &#39;;&#= 39; following statement<br> test.d(16): found &#39;}&#39; when expecting &#39;;&#39; following statemen= t<br>test.d(19): semicolon expected, not &#39;EOF&#39;<br>test.d(19): found= &#39;EOF&#39; when expecting &#39;}&#39; following compound statement<br> <br><br>Both of these little problems are not crucial, but they could bring= some very nice syntactic sugar on the API I am designing right now.<br>how= should I fix it?<br>If the actual behaviors are desired i&#39;d be interes= ted to know the arguments (well, i can imagine motivation for explicit conv= ersion, but for the delegate thing it&#39;s less clear to me). <br> <br>Thanks,<br><br>Nicolas<br> --0023544703441affc004b6aa98d5--
Jan 16 2012
parent Trass3r <un known.com> writes:
 StringHash sh = "SomeString"; // ok

That's the only thing that works. An implicit tag for constructors to allow all implicit conversions would really be helpful. In general we need finer control of implicit conversions. Just have a look at ProxyOf: https://github.com/D-Programming-Language/phobos/pull/300/files#L0R2670 That's madness, all of that code just for getting alias this without implicit conversion to the original type.
Jan 16 2012