www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Strange Error using parameterized opAssign for a struct

reply d coder <dlang.coder gmail.com> writes:
--0016e6dd95fd15cba704a73b6cd7
Content-Type: text/plain; charset=ISO-8859-1

Greetings All

I have a Struct (see minimized code below) which is failing for a simple
assignment. I am using DMD 2.053, and am getting an error:

 implicit.d(14): Error: cannot implicitly convert expression (foo1) of type

Am I doing something wrong, or have I hit a DMD bug? Kindly note that this happens only when I parameterize the struct using an Integral parameter, and works file when using string as parameter (as with struct Bar in the code). Regards - Puneet // File implicit.d struct Foo (size_t N) { void opAssign (size_t NN)(Foo!(NN) f) {/*do nothing*/} } struct Bar (string S) { void opAssign (string SS)(Bar!(SS) f) {/*do nothing*/} } void main() { Bar!"BAR1" bar1; Bar!"BAR2" bar2; bar2 = bar1; // this compiles fine Foo!4 foo1; Foo!4 foo2; foo2 = foo1; // compilation error } --0016e6dd95fd15cba704a73b6cd7 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div>Greetings All</div><div><br></div><div>I have a Struct (see minimized = code below) which is failing for a simple assignment. I am using DMD 2.053,= and am getting an error:</div><div><br></div><div>&gt; implicit.d(14): Err= or: cannot implicitly convert expression (foo1) of type Foo!(4) to Foo!(NN)= </div> <div><br></div><div>Am I doing something wrong, or have I hit a DMD bug? Ki= ndly note that this happens only when I parameterize the struct using an In= tegral parameter, and works file when using string as parameter (as with st= ruct Bar in the code).</div> <div><br></div><div>Regards</div><div>- Puneet</div><div><br></div><div>// = File implicit.d</div><div>struct Foo (size_t N) {</div><div>=A0 void opAssi= gn (size_t NN)(Foo!(NN) f) {/*do nothing*/}</div><div>}</div><div>struct Ba= r (string S) {</div> <div>=A0 void opAssign (string SS)(Bar!(SS) f) {/*do nothing*/}</div><div>}= </div><div>void main() {</div><div>=A0 Bar!&quot;BAR1&quot; bar1;</div><div=
=A0 Bar!&quot;BAR2&quot; bar2;</div><div>=A0 bar2 =3D bar1;<span style=3D"=

<div>=A0 Foo!4 foo1;</div><div>=A0 Foo!4 foo2;</div><div>=A0 foo2 =3D foo1;= <span style=3D"white-space:pre-wrap"> </span>// compilation error</div><d= iv>}</div><div><br></div> --0016e6dd95fd15cba704a73b6cd7--
Jul 04 2011
next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Mon, 04 Jul 2011 05:58:45 -0400, d coder <dlang.coder gmail.com> wrote:

 Greetings All

 I have a Struct (see minimized code below) which is failing for a simple  
 assignment. I am using DMD 2.053, and am getting an error:

 implicit.d(14): Error: cannot implicitly convert expression (foo1) of  
 type Foo!(4) to Foo!(NN)

Am I doing something wrong, or have I hit a DMD bug? Kindly note that this happens only when I parameterize the struct using an Integral parameter, and works file when using string as parameter (as with struct Bar in the code). Regards - Puneet

Yes and No. DMD has trouble deducing the correct template parameters for implicit function template instantiating when you make the template parameter the input to another template. The solution is to match a general type T and constrain it. (DMD can do these more complex matches inside an is expression, etc. So you can rewrite your code as: // File implicit.d struct Foo (size_t N) { void opAssign (T:Foo!NN,size_t NN)(T f) {/*do nothing*/} } struct Bar (string S) { void opAssign (string SS)(Bar!(SS) f) {/*do nothing*/} } void main() { Bar!"BAR1" bar1; Bar!"BAR2" bar2; bar2 = bar1; // this compiles fine Foo!4 foo1; Foo!4 foo2; foo2 = foo1; // Now compiles } Also, if you want to instantiate a Foo!NN, IIRC there's similar bug where the type becomes Foo!NN and not Foo!4. The solution is to use Foo!(NN+0) (or T) instead.
Jul 04 2011
prev sibling next sibling parent d coder <dlang.coder gmail.com> writes:
--0016e6dd8c9fd528c304a74c51ff
Content-Type: text/plain; charset=ISO-8859-1

Thanks Robert

Meanwhile, I also found that my code works it I change parameter type to int
instead of size_t. Looks like DMD fails because of some issue with implicit
conversions (or lack of it) between integral types.

Anyway the solution you provided is more elegant and I will adopt that.

Regards
- Puneet

--0016e6dd8c9fd528c304a74c51ff
Content-Type: text/html; charset=ISO-8859-1

Thanks Robert<div><br></div><div>Meanwhile, I also found that my code works it
I change parameter type to int instead of size_t. Looks like DMD fails because
of some issue with implicit conversions (or lack of it) between integral
types.</div>

<div><br></div><div>Anyway the solution you provided is more elegant and I will
adopt that.</div><div><br></div><div>Regards</div><div>- Puneet</div>

--0016e6dd8c9fd528c304a74c51ff--
Jul 04 2011
prev sibling next sibling parent d coder <dlang.coder gmail.com> writes:
--0016e6daa8ebc2f22b04a74cd22e
Content-Type: text/plain; charset=ISO-8859-1

Greetings Robert/All

Robert suggested that I put my opAssign method as:

void opAssign (T:Foo!NN,size_t NN)(T f) { }

That works. But I want to find out if it is possible to write the opAssign
template method with a conditional in the following form. This will help me
optimize code better. Kindly suggest what would come in place of .......
below.

void opAssign (T)(T f) if(is(T .......)) { }

Regards
- Puneet

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

<div>Greetings Robert/All</div><div><br></div><div>Robert suggested that I =
put my opAssign method as:</div><div><br></div><div>void opAssign (T:Foo!NN=
,size_t NN)(T f) { }</div><div><br></div><div>That works. But I want to fin=
d out if it is possible to write the opAssign template method with a condit=
ional in the following form. This will help me optimize code better. Kindly=
 suggest what would come in place of ....... below.</div>

<br><div>void opAssign (T)(T f)=A0if(is(T .......)) { }</div><div><br></div=
<div>Regards</div><div>- Puneet</div><div><br></div>

--0016e6daa8ebc2f22b04a74cd22e--
Jul 04 2011
prev sibling next sibling parent d coder <dlang.coder gmail.com> writes:
--bcaec5540bd6330bde04a74dbe86
Content-Type: text/plain; charset=ISO-8859-1

 Robert suggested that I put my opAssign method as:

 void opAssign (T:Foo!NN,size_t NN)(T f) { }

 That works. But I want to find out if it is possible to write the opAssign
 template method with a conditional in the following form. This will help me
 optimize code better. Kindly suggest what would come in place of .......
 below.

 void opAssign (T)(T f) if(is(T .......)) { }

void opAssign (T)(T f) if(is(T L : Foo!(NN,MM), int NN, int MM)) { } I found that the above declaration compiles. But again it compiles with int as parameter type. Fails for size_t. Any other idea? Regards - Puneet --bcaec5540bd6330bde04a74dbe86 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margi= n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div><br></div><= div>Robert suggested that I put my opAssign method as:</div><div class=3D"i= m"><div> <br></div><div>void opAssign (T:Foo!NN,size_t NN)(T f) { }</div><div><br></= div></div><div>That works. But I want to find out if it is possible to writ= e the opAssign template method with a conditional in the following form. Th= is will help me optimize code better. Kindly suggest what would come in pla= ce of ....... below.</div> <br><div>void opAssign (T)(T f)=A0if(is(T .......)) { }</div></blockquote><= div><br></div><div><br></div><div>void opAssign (T)(T f) if(is(T L : Foo!(N= N,MM), int NN, int MM)) { }</div><div><br></div><div>I found that the above= declaration compiles. But again it compiles with int as parameter type. Fa= ils for size_t.</div> <div><br></div><div>Any other idea?</div><div><br></div><div>Regards</div><= div>- Puneet</div></div> --bcaec5540bd6330bde04a74dbe86--
Jul 05 2011
prev sibling parent d coder <dlang.coder gmail.com> writes:
--bcaec5540bd65f3b9104a74fd8d0
Content-Type: text/plain; charset=ISO-8859-1

Hello Robert

As I try adding more code, I get into more and more issues with integral
parameters. See the following code:

Regards
- Puneet

// File implicit.d
alias int R;
// alias size_t R;
struct Foo (R N) {
  version(v1) {void opAssign (R NN)(Foo!NN f) {/*do nothing*/}}
  version(v2) {void opAssign (T:Foo!NN, R NN)(T f) {/*do nothing*/}}
   property Foo!(I) range(R I)() {return Foo!(I)();}
}
void main() {
  Foo!4 foo1;
  Foo!7 foo2;
  foo2 = foo1; // compiles with both v2 and v1/(only when R is aliased to
int)
  foo2 = foo1.range!4; // compiles with v1/int and v2/int -- does not
compile with R alias to size_t
  foo2 = foo1.range!2; // compiles only with v1/int -- does not compile with
v2 at all
}

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

Hello Robert<div><br></div><div>As I try adding more code, I get into more =
and more issues with integral parameters. See the following code:</div><div=
<br></div><div>Regards</div><div>- Puneet</div><div><br></div><div>// File=

alias int R;</div><div>// alias size_t R;</div><div>struct Foo (R N) {</div=
<div>=A0 version(v1) {void opAssign (R NN)(Foo!NN f) {/*do nothing*/}}</di=

}}</div> <div>=A0 property Foo!(I) range(R I)() {return Foo!(I)();}</div><div>}</di= v><div>void main() {</div><div>=A0 Foo!4 foo1;</div><div>=A0 Foo!7 foo2;</d= iv><div>=A0 foo2 =3D foo1;<span class=3D"Apple-tab-span" style=3D"white-spa= ce:pre"> </span>// compiles with both v2 and v1/(only when R is aliased to= int)</div> <div>=A0 foo2 =3D foo1.range!4;<span class=3D"Apple-tab-span" style=3D"whit= e-space:pre"> </span>// compiles with v1/int and v2/int -- does not compile= with R alias to size_t</div><div>=A0 foo2 =3D foo1.range!2;<span class=3D"= Apple-tab-span" style=3D"white-space:pre"> </span>// compiles only with v1/= int -- does not compile with v2 at all</div> <div>}</div><div><br></div></div> --bcaec5540bd65f3b9104a74fd8d0--
Jul 05 2011