On Monday, 13 November 2023 at 16:52:06 UTC, Paul Backus wrote:
> On Monday, 13 November 2023 at 16:23:05 UTC, Tim wrote:
> The visitor can already be extern(D)
. Only member functions overriding those in the base class need to be extern(C++)
. Other member functions can then use paratemers, which would be incompatible with extern(C++)
.
Wow, it really was that simple all along. Thanks for the tip!
That's not a complete solution. If you template the visitor and have some member functions that override the extern(C++) base class methods, then you will still end up with errors if you use any types that use non-mapable C++ types because of the mangling. For example:
extern(C++) class DMDVisitor
{
void visit(Expression e) {}
}
class MyVisitor(T) : DMDVisitor
{
T field;
extern(C++) override void visit(Expression e) {} // troubled line
}
Instantiating MyVisitor with a string type will issue an error at the troubled line because the mangler needs to take into account the template instance. Since C++ has no dynamic array correspondent you essentially cannot call MyVisitor.visit from C++ and therefore the compiler issues an error.
However, if you don't use templated visitors you are fine, you can just mark your introducing functions/fields as extern(D) and even if the class is extern(C++) it will work.