Short Version of Question
C++23 gives us a new way to write mixin classes (instead of CRTP). Is there any context where CRTP would still be preferred?
Summary of the Two Approaches
CRTP is a powerful idiom in C++ that leverages templates to automatically generate type-specific behavior at runtime. This is often used to create mixin classes.
C++23 introduces explicit object parameters, which allow the class name to be referenced explicitly in the parameter lists of non-static member functions. As a result, template non-static member functions can access the derived class, eliminating the need to specialize the mixin over the derived class.
Here is an example illustrating the old and new approach.
// classic CRTP (old approach)
template <typename T>
class MyMixin<T> {
// ...
void foo() {
// Stuff using T...
}
};
// have to specialize MyMixin over MyType
class MyType : public MyMixin<MyType> {
// ...
};
// explicit object parameter (C++23 approach)
class MyMixin {
// ...
template <typename T>
void foo(this T* self) {
// Stuff using T...
}
};
// better syntax for mixins
class MyType : public MyMixin {
// ...
};
Clearly, the new approach leads to cleaner syntax in the derived class. For instance, it lets us avoid gnarly things like this:
template<typename x, typename y, typename z, typename w>
class MyWackyContainer : public MyMixin<MyWackyContainer<x,y,z,w>>
since we don't have to provide a template parameter to MyMixin
with the new approach.
Full Question
Per the abstract of this paper (which addresses the previously mentioned problem),
While [adding explicit object parameters] has removed the need for using CRTP in many places, there still exist cases that must be expressed using this pattern.
The only functional difference I could think of between CRTP and the new approach, is that CRTP would let us reference the type when declaring non-function members and static member functions. But is there any situation where this is actually useful?
(Secondary question: Is my understanding correct? Did I miss anything?)