C++ overloaded operators and D

IgorStepanov via Digitalmars-d digitalmars-d at puremagic.com
Thu Nov 13 07:33:17 PST 2014


On Thursday, 13 November 2014 at 09:57:04 UTC, Marc Schütz wrote:
> On Wednesday, 12 November 2014 at 21:17:42 UTC, IgorStepanov 
> wrote:
>> On Wednesday, 12 November 2014 at 20:49:42 UTC, Marc Schütz 
>> wrote:
>>> On Wednesday, 12 November 2014 at 19:32:32 UTC, IgorStepanov 
>>> wrote:
>>>> On Wednesday, 12 November 2014 at 14:41:17 UTC, Marc Schütz 
>>>> wrote:
>>>>> On Wednesday, 12 November 2014 at 11:43:36 UTC, 
>>>>> IgorStepanov wrote:
>>>>>> C++ and D provides different behaviour for operator 
>>>>>> overloading.
>>>>>> D has a opIndex + opIndexAssign overloads, and if we want 
>>>>>> to map opIndex to operator[], we must to do something with 
>>>>>> opIndexAssign.
>>>>>
>>>>> operator[] can be mapped to opIndex just fine, right? Only 
>>>>> opIndexAssign wouldn't be accessible from C++ via an 
>>>>> operator, but that's because the feature doesn't exist. We 
>>>>> can still call it via its name opIndexAssign.
>>>>>
>>>>>> operator< and operator> can't be mapped to D. Same for 
>>>>>> operator&.
>>>>>
>>>>> That's true. Maybe we can just live with pragma(mangle) for 
>>>>> them, but use D's op... for all others?
>>>>>
>>>>>> Binary arithmetic operators can't be mapped to D, if them 
>>>>>> implemented as static functions:
>>>>>>
>>>>>> Foo operator+(int a, Foo f); //unable to map it to D, 
>>>>>> because static module-level Foo opAdd(int, Foo) will not 
>>>>>> provide the same behaviour as operator+ in D.
>>>>>> Thus: C++ and D overloaded operators should live in 
>>>>>> different worlds.
>>>>>
>>>>> Can't we map both static and member operators to opBinary 
>>>>> resp. opBinaryRight members in this case? How likely is it 
>>>>> that both are defined on the C++ side, and if they are, how 
>>>>> likely is it that they will behave differently?
>>>>
>>>> opBinary(Right) is a template-functions. You can't add 
>>>> previous declaration for it to struct:
>>>>
>>>> //C++
>>>> struct Foo
>>>> {
>>>>  Foo operator+(const Foo&);
>>>> };
>>>>
>>>> Foo operator+(int, const Foo&);
>>>>
>>>> //D
>>>> extern(C++)
>>>> struct struct Foo
>>>> {
>>>>  Foo opBinary!"+"(const ref Foo); //???
>>>
>>> I see...
>>>
>>>> }
>>>>
>>>> Foo opBinary!"+"(int, const ref Foo); //???
>>>
>>> But this would of course be opBinaryRight, and inside struct 
>>> Foo.
>>
>> What if
>> Foo operator+(const Bar&, const Foo&);?
>> Is it Foo.opBinaryRight, or Bar.opBinary, or both?
>
> For a C++ class interfaced from D: opBinary() in whichever of 
> the two classes it is defined.
>
> For a D class interfaced from C++: choose one, preferably 
> opBinary(), as it's the "natural" one.

It is too difficult, I think.
1. Compiler should generate static operator declaration (for 
linkage with C++) and method-wrapper.
2. We should use old non-template operators (like opAdd, opSub 
etc.) or introduce new kind of operators.
3. We should explain to the user how to use our operator bindings 
(explain to the user).

Anyway we may implement generic approach with pragma(mangle) now 
and add special rules for some operators if it be considered 
usefull. AFAIK, There are many objections aganist operators 
mapping are mentioned in n.g.


More information about the Digitalmars-d mailing list