@StoryTeller Он не претендует на семантическую идентичность. Он отмечен как возможная (безопасная) альтернатива, которая хороша во многих ситуациях. (Я постоянно использую это)
отрим следующий стандартный пример CRTP:
#include <iostream>
template<class Derived>
struct Base {
void f() { static_cast<Derived *>(this)->f(); }
void g() { static_cast<Derived *>(this)->g(); }
};
struct Foo : public Base<Foo> {
void f() { std::cout << 42 << std::endl; }
};
int main() {
Foo foo;
foo.f(); // just OK
foo.g(); // this will stack overflow and segfault
}
Если бы это было обычное виртуальное наследование, я мог бы пометить виртуальноеf
а такжеg
методы как чистые как
struct Base {
virtual void f() = 0;
virtual void g() = 0;
};
и получить ошибку времени компиляции оFoo
быть абстрактным. Но CRTP не предлагает такой защиты. Можно ли это как-то реализовать? Проверка времени выполнения тоже приемлема. Я думал о сравненииthis->f
указатель сstatic_cast<Derived *>(this)->f
, но не удалось заставить его работать.