Read more/u/RiotTony : Actually you can inline virtual function if you statically force the call of a precise function implementation
Here is a code sample:
// Compile with: icpc -std=c++11 -O2 main.cpp #include <stdio.h> class Base { public: virtual int foo() {return 42;} }; class Child : public Base { public: int foo() {return 69;} }; void bar(Child c) { printf("%d", c.Child::foo()); } void bar2(Child c) { printf("%d", c.Base::foo()); } int main(){ Child c; bar(c); bar2(c); }
If you run it you will get the output 6942 showing that first foo from the child was called and the foo from the base (despite using a child object). Also if you look at the assembly (-S option at compilation) you can see in the method bar and bar2 that the values 42 and 69 are hardcoded proving that the correct foo methods were inlined despite being virtual one.
Ofc this is a very specific use case but still, vir...
Yeah, there are ways around the virtual overhead, but the benefit of virtuals are that you don't need to know what it is that you're calling a given function on. Most use cases are just that - a collection of objects that are similar, but different enough to warrant different implementations of some of their parts. Another way to mitigate the cost of virtuals is to sort them by type. In that case you have far fewer I and D cache misses as you're usually calling the same functions. Modern HW is smart enough to predict the repeated branches.