digitalmars.D - C++ linkage specifics WRT virtual vs non-virtual member functions
- Roman Hargrave (17/17) Aug 13 2017 I'm writing some bindings and have run in to a dilemma due to the
- Petar Kirov [ZombineDev] (37/54) Aug 13 2017 W.r.t. virtual member functions, D's syntax is more similar to
- Timon Gehr (29/48) Aug 13 2017 You can create one (this will look nicer with static foreach):
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. 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?
Aug 13 2017
On Sunday, 13 August 2017 at 07:18:31 UTC, 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. 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?W.r.t. virtual member functions, D's syntax is more similar to Java than to C++, in that class member functions are virtual by default, unless marked as `final`. So to declare the following C++ class: class Base { virtual int fun(); int gun(); }; In D you have to do the following: extern (C++) class Base { int fun(); final int gun(); } Like all other attributes, you can group multiple members to which you want to apply the `final` attribute by either: class C { final { int gun(); int hun(); } } Or: class C { final: int gun(); int hun(); } Though be aware that unlike the protection attributes (public, private), there's no way to undo 'final:', so if you use it, you would have to move it with all the non-virtual methods to the bottom of the class definition.
Aug 13 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.
Aug 13 2017