Rozważmy następujący standardowy przykład CRTP:Protect CRTP wzór ze stosu przepełnione w „czystej wirtualny” zwraca
#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
}
Jeśli to był regularny wirtualnego dziedziczenie mogę mieć znak wirtualnych f
i g
metody jak czysta jak
struct Base {
virtual void f() = 0;
virtual void g() = 0;
};
i uzyskaj komunikat o błędzie kompilacji o numerze Foo
będącym abstraktem. Ale CRTP nie oferuje takiej ochrony. Czy mogę go jakoś wdrożyć? Sprawdzanie czasu pracy jest również akceptowalne. Pomyślałem o porównaniu wskaźnika this->f
z static_cast<Derived *>(this)->f
, ale nie udało się go uruchomić.
Nie wiem, czy jest to zachowanie zdefiniowane w standardzie, ale można użyć 'static_assert' wewnątrz' Base :: g', którego 'i Derived :: g! = & Base :: g'. –
Holt
Wygląda na to, że działa również: http://coliru.stacked-crooked.com/a/80021ad0bfb7aa47 –
@ JohannesSchaub-litb To jest sprytne! Powinieneś napisać odpowiedź. – Yakk