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