The problem with opX_r (or more powerful template specialization)

Bill Baxter wbaxter at gmail.com
Wed Nov 8 13:15:00 PST 2006


Sean Kelly wrote:
> Bill Baxter wrote:
> 
>> 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.
> 
> 
> Hrm, true enough.
> 
>> 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.
> 
> 
> That's the most flexible certainly, but it often means friend functions 
> so data is accessible for the operation.  I think it's often easier to 
> implement addition simply by creating a temporary and using AddAssign, 
> expression templates aside.

Right.  I was about to say that, actually.  In most cases your 
out-of-class add operator is just implemented in terms of one or the 
other opAddAssign (operator+=) functinos, so you don't need any special 
access to the internals of the class.

And that means that for the a+b case you're making the choice of which 
add operator to use explicitly by whether you use b's += or a's +=.

I guess that's what's missing in D, some way to write an operator 
function outside of both A and B that makes the final decision.

--bb



More information about the Digitalmars-d mailing list