C++ linkage specifics WRT virtual vs non-virtual member functions

Timon Gehr via Digitalmars-d digitalmars-d at puremagic.com
Sun Aug 13 07:08:08 PDT 2017


On 13.08.2017 09:18, Roman Hargrave wrote:
> I'm writing some bindings and have run in to a dilemma due to the lack 
> of explicit information on how the D compiler "decides" to use virtual 
> dispatch for a member function or not.
> 
> Specifically, I have a C++ library that _explicitly_ marks some member 
> functions as virtual, in addition to a plethora of non-virtual functions.
> 
> I would like to be certain that the D compiler understands that I would 
> like it to treat those functions as virtual functions, but unlike C++ 
> where there is a `virtual` classifier for functions, D does not appear 
> to have such a facility.
> ...

You can create one (this will look nicer with static foreach):

struct virtual{}
mixin template CheckVirtual(T){
     import std.traits: isFinal, hasUDA;
     mixin({string r="";
     foreach(m;__traits(allMembers,T)){
         r~=`static 
assert(isFinal!(T.`~m~`)||hasUDA!(T.`~m~`,virtual),"'`~T.stringof~`.`~m~`' 
is neither final nor @virtual");`;
         r~=`static 
assert(!isFinal!(T.`~m~`)||!hasUDA!(T.`~m~`,virtual),"'`~T.stringof~`.`~m~`' 
is both final and @virtual");`;
     }
     return r;}());
}

// example:
extern(C++) class C{
     final void foo(){} // ok
     @virtual void bar(){} // ok
     void baz(){} // Error: static assert  "'C.baz' is neither final not 
@virtual"
     @virtual final void qux(){} // Error: static assert  "'C.qux' is 
both final and @virtual"
}
mixin CheckVirtual!C;



> The C++ interop documentation suggests that both non- and virtual 
> functions are supported, but further suggests that it only treats 
> inherited functions as virtual with no method of explicitly requesting 
> virtual dispatch for that method.
> 
> As far as I can tell, all specified member functions in a class with C++ 
> linkage are assumed to be non-virtual unless they are overriden?

All member functions are virtual by default. Only member functions 
explicitly marked as `final` are not virtual. The code above makes both 
explicit to help prevent mistakes.


More information about the Digitalmars-d mailing list