Describe the shape of a CRTP strategy base that calls into the derived class with no virtual function, then state the two situations in which you would still choose a virtual interface for the same code, and the two costs CRTP adds to the build.
Describe the shape of a CRTP strategy base that calls into the derived class with no virtual function, then state the two situations in which you would still choose a virtual interface for the same code, and the two costs CRTP adds to the build.
Approach: Template the base on the derived type and cast the this pointer inside the base, then ask what breaks once the set of derived types is unknown until runtime.
The base is a class template parameterised on the derived type, and each base method uses static_cast on this to reach the derived pointer and calls the derived method, so every call resolves at compile time and inlines, which is static polymorphism. You still choose a virtual interface when the concrete type is selected at runtime, for example a strategy named in a config file or loaded from a shared library, and when you need a heterogeneous container of strategies, since a CRTP base is a distinct type for every derived class and cannot be stored in one vector of base pointers. The two build costs are compile time and binary size, because every instantiation is a fresh copy of the code, and error messages that point into template instantiation rather than at the mistake.
Follow-up: How would you make a missing derived method produce an error naming that method rather than a template instantiation trace?
Key concepts: crtp, static polymorphism, static_cast, heterogeneous container.