On Thu, 11 Mar 2010 19:15:37 -0500, Trass3r <[email protected]> wrote:

I stumbled across this while playing with operator overloading. Since they are now function templates, this becomes an issue.

struct Vector2(T)
{
        T x;
        T y;

        /// element-wise operations, +, -,
        Vector2 opBinary(string op)(ref Vector2 v)
        {
mixin("return Vector2!(T)( cast(T)(x " ~ op ~ " v.x), cast(T)(y " ~ op ~ " v.y) );");
        }

        /// operation with scalar
        Vector2 opBinary(string op)(int i)
        {
mixin("return Vector2!(T) ( cast(T)(x " ~ op ~ " i), cast(T)(y " ~ op ~ " i) );");
        }
}

This yields:
template instance opBinary!("+") matches more than one template declaration

Of course this can be circumvented by using
opBinary(string op, U:Vector2)(U v)
opBinary(string op, U:int)(U v)


But is this how it's supposed to be done? Couldn't the compiler detect that itself?

The issue is with two things.

First, there are two instantiations of the template. You have to realize that a template is somewhat of a namespace, and they do not append to eachother. Think about it this way, a template function is really a shortcut for this:

template fn(T)
{
    fn(args) {...}
}

So what you have done is:

template fn(T)
{
   fn(args1) {...}
}

template fn(T)
{
   fn(args2) {...}
}

The compiler doesn't combine the two templates together, so it doesn't know which namespace you are talking about.

I tried something like this:

template fn(T)
{
   fn(args1) {...}
   fn(args2) {...}
}

but this doesn't work, because the compiler refuses to call the function via fn!(T)(args1).

I think the only option you are faced with at the moment is to include the argument type in the template specification, thereby separating the namespace.

You should file a bug on this. I think it's not a good result of the new operator overloading regime. However, I think it can be fixed, by either handling template function overloads, or having the compiler rewrite

x + b

as

x.opBinary!("+").opBinary(b);

since we aren't even using IFTI here. Then my proposed overloaded template functions will work.

-Steve

Reply via email to