On Saturday, November 17, 2018 11:09:51 PM MST Carl Sturtivant via Digitalmars-d-learn wrote: > On Thursday, 15 November 2018 at 19:01:45 UTC, Ali Çehreli wrote: > > On 11/15/2018 09:14 AM, Carl Sturtivant wrote: > > > opDispatch is special in that it allows for functions to be > > > > added to a > > > > > class or struct when undefined overtly but used elsewhere but > > > > it seems > > > > > those functions sadly are final. > > > > > > Can anything useful be done to remedy the situation? > > > > For the compiler to be able to make all opDispatch > > instantiations virtual, it would have to first see all calls > > that generate opDispatch instantiations. (Impossible in the > > presence of separate compilation.) > > > > Only then the compiler would know how large the vtbl of the > > base class should be and what member functions of the derived > > class are overrides of those virtual functions. > > I suppose it's such administrative difficulties that led to D > defining anything that might conceivably be overridden to be > virtual, whether or not actually overridden.
The issue with templated functions is that you don't have the full list of instantiations when the base class is compiled, whereas as I understand it, the issue with virtual-by-default is more of an issue of choosing code correctness by default over efficiency by default. You can get some fun, subtle bugs in C++ when you call non-virtual functions in circumstances where they were overridden and used as if they were virtual. So, by making all public and protected class member functions virtual by default and not allowing non-virtual functions to be overridden, it prevents a whole class of bugs. It _does_ have some performance downsides in that it easily leads to functions being virtual when they don't need to be, which can be gotten around with some extra effort, but it's effectively favoring correctness by default over efficiency. And for a lot of programs, it's a great tradeoff, especially when the whole point of classes in D is to use inheritance and polymorphism, and the cases where you don't need it, you use a struct. For the rest, final can be used to devirtualize a function as long as it's not overriding a function. To avoid bugs in the same way that we currently do without having virtual be the default, we probably would have had to make it illegal to override any class functions unless they were explicitly virtual, which would have created a different set of problems. And whether that would be better or worse is a matter of debate. In the end, it's a matter of tradeoffs, and which is better is likely to depend on how your applications benefit from and use the feature. If most of your class functions are used polymorphically, then having to mark them as virtual or having to put virtual: at the top of your class would get really annoying, whereas if you typically have only a few virtual functions and then lots of non-virtual property functions (like the AAA guys apparently like to do), then having to mark things with final to devirtualize them is very annoying. There's no pleasing everyone. Either way, allowing overriding non-virtual functions like C++ does would just be begging for bugs. - Jonathan M Davis