opBinary failes with templates

KennyTM~ kennytm at gmail.com
Wed Jul 27 14:39:44 PDT 2011


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.


More information about the Digitalmars-d mailing list