Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protect CRTP pattern from stack overflowing in "pure virtual" calls

Tags:

Consider the following standard CRTP example:

#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 } 

If this was regular virtual inheritance I could have mark virtual f and g methods as pure like

struct Base {     virtual void f() = 0;     virtual void g() = 0; }; 

and get a compile time error about Foo being abstract. But CRTP offers no such protection. Can I implement it somehow? Runtime check is acceptable too. I thought about comparing this->f pointer with static_cast<Derived *>(this)->f, but didn't manage to make it work.

like image 719
uranix Avatar asked Jul 18 '17 09:07

uranix


1 Answers

You can assert at compile time that the two pointers to member functions are different, e.g.:

template<class Derived> struct Base {     void g() {         static_assert(&Derived::g != &Base<Derived>::g,                       "Derived classes must implement g().");          static_cast<Derived *>(this)->g();      } }; 
like image 182
Holt Avatar answered Jun 05 '23 10:06

Holt