opBinary failes with templates

simendsjo simendsjo at gmail.com
Wed Jul 27 15:07:18 PDT 2011


On 27.07.2011 23:39, KennyTM~ wrote:
> On Jul 28, 11 05:25, Asger Dam Hoedt wrote:
>> 2011/7/27 Steven Schveighoffer <schveiguy at yahoo.com
>> <mailto:schveiguy at yahoo.com>>
>>
>> On Wed, 27 Jul 2011 15:48:24 -0400, Asger Dam Hoedt
>> <asgerhoedt at gmail.com <mailto:asgerhoedt at gmail.com>> wrote:
>>
>> Hey
>>
>> I've very recently started playing around with D, but I seem to
>> have hit my
>> head against a bug in dmd. I want to create a Vector class
>> templated with
>> its dimension. This works fine until I try to overload the +
>> operator for my
>> vector and use it. I then get the error
>>
>> Error: incompatible types for ((vec) + (vec)): 'Vector!(3)' and
>> 'Vector!(3)'
>>
>> I've boiled it down to a small example
>>
>> struct Vector(int D) {
>> float es[D];
>>
>> public:
>> this(immutable float x, immutable float y, immutable float z) {
>> es[0] = x; es[1] = y; es[2] = z;
>> }
>>
>> Vector!(D) opBinary(string s)(immutable Vector!(D) rhs) if
>> (s == "+") {
>> Vector!(D) ret;
>> for(int i = 0; i < D; ++i)
>> ret.es <http://ret.es>[i] = es[i] + rhs.es <http://rhs.es>[i];
>> return ret;
>> }
>>
>> }
>>
>> alias Vector!(3) Vector3;
>>
>> void main() {
>> Vector3 vec = Vector3(0,1,2);
>> vec = vec.opBinary!("+")(vec); // This works fine
>> vec = vec + vec; // This line fails miserably
>> }
>>
>> If I replace the template argument in for the argument rhs with
>> 3, then
>> everything works, but that's not really a nice solution :)
>>
>> Is it me trying to use templates in a way they aren't meant to
>> be used or is
>> this a bug in dmd? If it is a bug, does anyone have an idea how
>> to solve
>> this? I wouldn't mind fixing it in dmd myself, I just need some
>> guidelines.
>>
>>
>> It is a bug, someone just brought up almost exactly this problem in
>> d.learn.
>>
>> http://www.digitalmars.com/__webnews/newsgroups.php?art___group=digitalmars.D.learn&__article_id=28455
>>
>> <http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learn&article_id=28455>
>>
>>
>> The proper workaround (and actually, the cleaner solution) is to use
>> Vector and not Vector!D. Inside a template, the name of the
>> template is the same as if you invoked the template with the same
>> template parameters.
>>
>> If you actually do need a different value for D, I'm not sure what
>> works.
>>
>> -Steve
>>
>>
>> Oh nice. I'll go with the clean solution then and disregard the bug for
>> now. Thanks for the quick help.
>>
>> /asger
>
> Actually you shouldn't need to write a vector struct if "+" is all it
> required, as D supports array operation already:
>
>
>
> void main() {
> float[3] x = [1, 3, 5], y = [5, -6, 2];
> x[] = x[] + y[];
> assert(x == [6, -3, 7]);
> }
>
>
> It is also more efficient than the for-loop since this could use SIMD
> operations in some cases.

The last time I tried to use vector ops, they failed for all but the 
most straight forward use-cases. I was told it wasn't fully implemented 
yet. Is this still the case, or are they ready for prime-time?


More information about the Digitalmars-d mailing list