This is cool. From my perspective, the main thing you get with this is less memory usage. Since less things are template instantiated, you'll have smaller programs. Unfortunately, converting CRTP to this is a binary interface change, so it could cause wide churn.
The other limitation of this is that each calling site must specify the type it wants to use. This is more generic because the base type is no longer tied to a single type. However, it could lead to bad states if callers mix calls with multiple types on the same base instance which isn't expecting it.
The other limitation of this is that each calling site must specify the type it wants to use. This is more generic because the base type is no longer tied to a single type. However, it could lead to bad states if callers mix calls with multiple types on the same base instance which isn't expecting it.