The problem with opX_r (or more powerful template specialization)

Bill Baxter dnewsgroup at billbaxter.com
Tue Nov 7 16:49:21 PST 2006


Sean Kelly wrote:
> Bruno Medeiros wrote:
>> Sean Kelly wrote:
>>> Oskar Linde wrote:
>>>>
>>>> 1) Change the opX_r overloading rules, so that
>>>>
>>>> opX_r(T)(T x) {...}
>>>> opX(T)(T x) {...}
>>>>
>>>> can coexist. opX_r is picked only of no opX overload is found.
>>>
>>> I thought operators worked this way:
>>>
>>>     x = y - z;
>>>
>>> 1. Call y.opSub(z) if it exists.
>>> 2. If not, call z.opSub_r(y).
>>>
>>> ie. I had thought that the opX_r operations were for situations where 
>>> the called object was on the right-hand side of the operation.  
>>> Assuming this were true, there should be no problem in having opX and 
>>> opX_r coexist peacefully.
>>>
>>
>> Nope. From the spec:
>> "1. The expression is rewritten as both:
>> a.opfunc(b)
>> b.opfunc_r(a)
>> If any a.opfunc or b.opfunc_r functions exist, then overloading is 
>> applied across all of them and the best match is used."
>>
>> So those two forms (direct and reverse) compete on equal priority.
> 
> So if a implemented an opSub(b) and b implemented an opSub_r(a) I'd get 
> a compiler error about an ambiguous overload?  This seems somewhat 
> sub-optimal.  Why was it implemented this way?

I think it makes sense.  Given the expression  "a + b", it's not clear 
which add operation should be used.

You can disambiguate by calling the method explicitly: a.opAdd(b).

Better would be if D had out-of-class operators.  Then you could just 
have a free function - T opAdd(A a, B b) and you don't have to worry 
about whether a or b owns this particular combination of addition.  I 
believe the general rule of thumb in C++ is that operators that don't 
modify their arguments (like +-/*) should be stand-alone functions.

--bb



More information about the Digitalmars-d mailing list