#include <iostream>
void doSomething (int x) {std::cout << "Do something with " << x << std::endl;}
template <typename T, typename D>
void helper(const D& base)
{
// Code A
if (base.T::foo() < 6) {
// Code B
}
doSomething (base.T::goo());
// Code C
if (base.T::hoo() > 10) {
// Code D
}
}
struct Base {
virtual ~Base() = default;
virtual int foo() const {return 5;}
virtual int goo() const {return 6;}
virtual int hoo() const {return 7;}
void noTemplatePattern() const
{
helper<Base>(*this);
}
#if 0 // activate this code if you want this method accessible from base
virtual void templatePattern() const = 0;
#endif
};
template <typename Derived>
struct BaseImpl : Base {
void templatePattern() const /*override final*/ {
helper<Derived>(static_cast<const Derived&>(*this));
}
};
struct Derived : BaseImpl<Derived> {
virtual int foo() const override {return 12;}
virtual int goo() const override {return 13;}
virtual int hoo() const override {return 14;}
};
int main() {
Derived d;
d.noTemplatePattern();
d.templatePattern();
}