| Thread overview |
|---|
July 04, 2011 Strange Error using parameterized opAssign for a struct | ||||
|---|---|---|---|---|
| ||||
Attachments:
| 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
// 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
}
| |||
July 04, 2011 Re: Strange Error using parameterized opAssign for a struct | ||||
|---|---|---|---|---|
| ||||
Posted in reply to d coder | 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.
| |||
July 05, 2011 Re: Strange Error using parameterized opAssign for a struct | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Robert Jacques Attachments:
| 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 | |||
July 05, 2011 Re: Strange Error using parameterized opAssign for a struct | ||||
|---|---|---|---|---|
| ||||
Attachments:
| 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
| |||
July 05, 2011 Re: Strange Error using parameterized opAssign for a struct | ||||
|---|---|---|---|---|
| ||||
Attachments:
| >
>
> 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
| |||
July 05, 2011 Re: Strange Error using parameterized opAssign for a struct | ||||
|---|---|---|---|---|
| ||||
Attachments:
| 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
}
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply