C++ overloaded operators and D

IgorStepanov via Digitalmars-d digitalmars-d at puremagic.com
Wed Nov 12 11:32:31 PST 2014


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); //???
}

Foo opBinary!"+"(int, const ref Foo); //???

May be some cases can be mapped to D, but these cases require 
special consideration.

I suggest a generic rule.

extern(C++)
struct struct Foo
{
     pragma(mangle,  cppOpAdd)Foo op_add(const ref Foo);
}

extern(C++)
pragma(mangle,  cppOpAdd)Foo op_add2(int, const ref Foo);

Now, if you want to use this overloaded operators as D operators, 
you may wrap it to D operator-functions.

extern(C++)
struct struct Foo
{
     pragma(mangle,  cppOpAdd) Foo op_add(const ref Foo);

     Foo opBinary(string s)(const ref Foo rvl) if (s == "+")
     {
          return op_add(rvl);
     }

     Foo opBinaryRight(string s)(int lvl) if (s == "+")
     {
          return op_add2(lvl, this);
     }
}

extern(C++)
pragma(mangle,  cppOpAdd)Foo op_add2(int, const ref Foo);

This way allows access to C++ operators and doesn't add new rules 
into the language.


More information about the Digitalmars-d mailing list