Hacker News new | ask | show | jobs
by jandrewrogers 1459 days ago
Can you give some examples of what you mean? I use static polymorphism in C++ routinely and haven't felt particularly limited by it.
1 comments

Sure. I guess template-based polymorphism is alright for code dispatch. But if you want to store the different types of objects involved you have limited choices. There's no straight-forward support for sum types. std::variant is fairly new, has a cumbersome API, and is quite slow (ballpark the same as virtual calls). There's no support for methods on enums nor anything for customizing the fields of different enum constants. There's also no pattern matching or other really convenient way of deconstructing variants.

So while it's there, I would say that the oo virtual method style is much better supported, although storage for those usually requires some type heap allocation.

Okay, yeah, I would broadly agree with this. I think most people use template-based polymorphism, which is pretty flexible in practice. The use of virtual methods is verboten for many common use cases of C++, due to the necessity of being in paged memory, so constructions for dealing with polymorphism without virtual methods are commonplace. And std::variant is a bit of a hot mess.
> The use of virtual methods is verboten for many common use cases of C++, due to the necessity of being in paged memory

I wasn't aware of this. Maybe I'm just out of the loop. Do you know where one can I learn more about this? I'm desperately trying to reduce the number of virtual calls in our codebase, but I'm hitting the aforementioned problems.

It is a design problem endemic to database engines and probably file systems. A design requirement for most of the dynamic runtime data structures is that they can be directly paged to storage, either in whole or in part, and be paged from storage in an arbitrarily distant future on different machines with different compilers. In order to make this work, all data types used in pageable data structures must 1) have a size and alignment that is not compiler-dependent so that page types always have a size that is a strict multiple of the I/O page size and 2) not contain any pointers. This precludes vtables.

This has traditionally been managed with CRTP, tagged unions, etc with some scaffolding to make it convenient and compliant with strict aliasing rules. Ideally, almost all of the dynamic polymorphism is pulled up to the level of the page types, an opaque blob of I/O friendly complex data structure, minimizing the amount you have to do. It is also important to note that JIT-ing has replaced many of the use cases for dynamic dispatch e.g. adding user-defined schemas at runtime.

None of which may apply to your use case. Some things inherently require an unfortunate amount of dynamic dispatch.

Virtual methods are about dispatch tables (which are built at compile time) and have nothing to do with paging. Nothing. At all.
"hmm, you call it an 'enum class' yet somehow I cannot define methods on it"