Thread overview | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
October 18, 2012 opCast using in template struct | ||||
---|---|---|---|---|
| ||||
Hello. How to cast template struct to itself? struct vec(string S,T=double) { T[S.length] data; auto opCast(string K,E)() if( S.length == K.length && is( T : E ) ) { vec!(K,E) ret; foreach( i, ref m; ret.data ) m = data[i]; return ret; } } unittest { alias vec!"xyz" dvec3; alias vec!("rbg",float) fcol3; auto a = dvec3([1,2,3]); auto b = fcol3(); b = a; #1 assert( b.data == [1,2,3] ); } #1 Error: cannot implicitly convert expression (a) of type vec!("xyz") to vec!("rbg",float) |
October 18, 2012 Re: opCast using in template struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Oleg | On 2012-10-18, 16:54, Oleg wrote: > Hello. How to cast template struct to itself? > > struct vec(string S,T=double) > { > T[S.length] data; > auto opCast(string K,E)() > if( S.length == K.length && > is( T : E ) ) > { > vec!(K,E) ret; > foreach( i, ref m; ret.data ) > m = data[i]; > return ret; > } > } > > unittest > { > alias vec!"xyz" dvec3; > alias vec!("rbg",float) fcol3; > auto a = dvec3([1,2,3]); > auto b = fcol3(); > b = a; #1 > assert( b.data == [1,2,3] ); > } > > #1 Error: cannot implicitly convert expression (a) > of type vec!("xyz") to vec!("rbg",float) I don't see a cast there. Do you? What you want is to overload the assignment operator, opAssign: struct vec(string S,T=double) { T[S.length] data; void opAssign(string K,E)(vec!(K,E) value) if( S.length == K.length && is( E : T ) ) { foreach( i, ref m; value.data ) data[i] = m; } } unittest { alias vec!"xyz" dvec3; alias vec!("rbg",float) fcol3; auto a = dvec3([1,2,3]); auto b = fcol3(); b = a; #1 assert( b.data == [1,2,3] ); } -- Simen |
October 18, 2012 Re: opCast using in template struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | Sorry. My problem more complex and my simplification is not correct. I want use mixin for math operations. mixin template vectOp( string DataName, int DataLen, T, vecType ) { mixin( "alias " ~ DataName ~ " this;" ); .... auto opBinary(string op,E)( E[DataLen] b ) .... auto opBinary(string op,E)( E[] b ) .... auto opOpBinary(string op,E)( E[] b ) .... auto opOpBinary(string op,E)( E[DataLen] b ) .... .... } struct vec(string S,T=double) { T[S.length] data; mixin vectOp( "data", S.length, T, vec!(S,T) ); } unittest{ vec!"xyz" a; vec!"xyz" b; a += b; } and it isn't work Error: 'a += b' is not a scalar, it is a vec!("xyz") Error: 'a._data' is not of arithmetic type, it is a double[3LU] Error: 'b._data' is not of arithmetic type, it is a double[3LU] |
October 18, 2012 Re: opCast using in template struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Oleg | On 2012-10-18, 17:45, Oleg wrote: > Sorry. My problem more complex and my simplification is not correct. > I want use mixin for math operations. > > mixin template vectOp( string DataName, int DataLen, T, vecType ) > { > mixin( "alias " ~ DataName ~ " this;" ); > .... > auto opBinary(string op,E)( E[DataLen] b ) .... > auto opBinary(string op,E)( E[] b ) .... > auto opOpBinary(string op,E)( E[] b ) .... > auto opOpBinary(string op,E)( E[DataLen] b ) .... > .... > } > > struct vec(string S,T=double) > { > T[S.length] data; > mixin vectOp( "data", S.length, T, vec!(S,T) ); > } > > unittest{ > vec!"xyz" a; > vec!"xyz" b; > a += b; > } > > and it isn't work > > Error: 'a += b' is not a scalar, it is a vec!("xyz") > Error: 'a._data' is not of arithmetic type, it is a double[3LU] > Error: 'b._data' is not of arithmetic type, it is a double[3LU] I see you have opOpBinary there - should those be opOpAssign? -- Simen |
October 18, 2012 Re: opCast using in template struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | On Thursday, 18 October 2012 at 18:12:49 UTC, Simen Kjaeraas wrote:
> I see you have opOpBinary there - should those be opOpAssign?
Probably. It's an easy mistake to make. Maybe the compiler should issue a warning when opAssign attempts and fails and opOpBinary is defined.
|
October 18, 2012 Re: opCast using in template struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Era Scarecrow | Era Scarecrow:
> It's an easy mistake to make. Maybe the compiler should issue a warning when opAssign attempts and fails and opOpBinary is defined.
If you have strong feelings about this, then add a Bugzilla entry.
There are other cases. Generally the D compiler should add some warnings that help against operator overloading mistakes.
Bye,
bearophile
|
October 18, 2012 Re: opCast using in template struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 10/18/2012 11:45 PM, bearophile wrote: > Era Scarecrow: > >> It's an easy mistake to make. Maybe the compiler should issue a >> warning when opAssign attempts and fails and opOpBinary is defined. > This would have to be implemented very carefully. There are enough hard to reproduce symbol resolution bugs already. It does not get better by introducing hidden and unnecessary lookups. > If you have strong feelings about this, then add a Bugzilla entry. > > There are other cases. Generally the D compiler should add some warnings > that help against operator overloading mistakes. > > Bye, > bearophile I don't think that operator overloading gives rise to distinct mistakes. For example, better error messages that just specify the expected name, as in other cases of undefined identifiers, would already fix this. |
October 18, 2012 Re: opCast using in template struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Thursday, 18 October 2012 at 22:07:55 UTC, Timon Gehr wrote:
> On 10/18/2012 11:45 PM, bearophile wrote:
>> There are other cases. Generally the D compiler should add some warnings that help against operator overloading mistakes.
>
> I don't think that operator overloading gives rise to distinct mistakes. For example, better error messages that just specify the expected name, as in other cases of undefined identifiers, would already fix this.
Inside a function a badly named identifier becomes obvious since it outright tells you. But with regards to opOpAssign and other operator overloading I see the error message and I see the call but I don't see why it fails. Then I'll try adjusting the signature on my function, not realizing it never sees it in the first place due to misspelling.
Maybe.. A general warning when something starts with 'op(Op)?[A-Z]' but doesn't actually qualify as any of the override-able operators? That seems sensible...
|
October 18, 2012 Re: opCast using in template struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Era Scarecrow | Era Scarecrow:
> Maybe.. A general warning when something starts with 'op(Op)?[A-Z]' but doesn't actually qualify as any of the override-able operators? That seems sensible...
Regarding operator overloading there are several situations worth warning the programmer of. The D compilers should be improved on this.
Bye,
bearophile
|
October 18, 2012 Re: opCast using in template struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Era Scarecrow | On 10/19/2012 01:05 AM, Era Scarecrow wrote: > On Thursday, 18 October 2012 at 22:07:55 UTC, Timon Gehr wrote: >> On 10/18/2012 11:45 PM, bearophile wrote: >>> There are other cases. Generally the D compiler should add some >>> warnings that help against operator overloading mistakes. >> >> I don't think that operator overloading gives rise to distinct >> mistakes. For example, better error messages that just specify the >> expected name, as in other cases of undefined identifiers, would >> already fix this. > > Inside a function a badly named identifier becomes obvious since it > outright tells you. But with regards to opOpAssign and other operator > overloading I see the error message and I see the call but I don't see > why it fails. My suggestion was something like: error: expression 'e' of type 'S' is not of arithmetic type and it does not define opOpAssign!"+". The compiler should indicate exactly why it fails. If this is not enough, then the programmer certainly deserves the headache. > Then I'll try adjusting the signature on my function, not > realizing it never sees it in the first place due to misspelling. > If the issue _is_ with the signature, then the compiler should tell you. That is the (secondary) job of the compiler. > Maybe.. A general warning when something starts with 'op(Op)?[A-Z]' 'op[A-Z]' > but doesn't actually qualify as any of the override-able operators? That > seems sensible... That is a lot better, but what if the typo is within the first 3 characters? :o) |
Copyright © 1999-2021 by the D Language Foundation