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