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.