3

I am trying to work out some way to enforce contract between base CRTP class and the derived one. When using dynamic polymprhpism, one can simply do:

struct foo{
    virtual bar() = 0;
};

And the compiler will make sure that the method bar is implemented in deriving class, otherwise it will give (more or less) meaningful error message. Now the best I could get with CRTP to is something like this:

template<class Derived>
struct base {
    void stuff(){
        static_cast<Derived &>(*this).baz();  
    }
};

Which will somehow enforce implementation of baz in derived class but is not really readable and clear what the contract between base and derived class is. So my question is, is there a way to do this better? I am aware of C++20 Concepts and that they would be perfect solution for this case, but I am looking for C++11/C++14 solution to make it as clean as possible.

bartop
  • 9,971
  • 1
  • 23
  • 54

1 Answers1

3

Since the derived class is always incomplete when a base is defined one solution I use is to delay "concept check" instantiation using a defaulted template parameter:

template<class T>
using has_baz = decltype(std::declval<T&>().baz());

template<class Derived>
struct base{
  template<class T = Derived, has_baz<T>* =nullptr>
  void stuff(){/*...*/}
  };

Notice, c++20 concepts will not solve this special issue and the delaying of the concept check will still be necessary. The advantage is that the compilation error will be clearer.

Demo

Oliv
  • 17,610
  • 1
  • 29
  • 72