#include <iostream>
template<typename T>
class Enforcer: public T
{
public:
template<typename... Args>
Enforcer(Args&&... arg): T(std::forward<Args>(arg)...)
{
}
void init() override
{
T::init();
T::BaseClass::init();
}
};
class Base
{
public:
virtual void init() = 0;
private:
bool initialized = false;
};
void Base::init()
{
std::cout << "Called from base!\n";
initialized = true;
}
class Derived: public Base
{
friend class Enforcer<Derived>;
public:
void init() override
{
std::cout << "Called from derived!\n";
}
private:
Derived()
{
}
private:
using BaseClass = Base;
private:
bool initialized = false;
};
int main()
{
Enforcer<Derived> d;
d.init();
}
CiNpbmNsdWRlIDxpb3N0cmVhbT4KCgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpjbGFzcyBFbmZvcmNlcjogcHVibGljIFQKewpwdWJsaWM6CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZS4uLiBBcmdzPgogICAgRW5mb3JjZXIoQXJncyYmLi4uIGFyZyk6IFQoc3RkOjpmb3J3YXJkPEFyZ3M+KGFyZykuLi4pCiAgICB7CiAgICAgICAgCiAgICB9CgogICAgdm9pZCBpbml0KCkgb3ZlcnJpZGUKICAgIHsKICAgICAgICBUOjppbml0KCk7CiAgICAgICAgVDo6QmFzZUNsYXNzOjppbml0KCk7CiAgICB9Cn07CgpjbGFzcyBCYXNlCnsKcHVibGljOgogICAgdmlydHVhbCB2b2lkIGluaXQoKSA9IDA7CnByaXZhdGU6CiAgICBib29sIGluaXRpYWxpemVkID0gZmFsc2U7Cn07Cgp2b2lkIEJhc2U6OmluaXQoKSAKewogICAgc3RkOjpjb3V0IDw8ICJDYWxsZWQgZnJvbSBiYXNlIVxuIjsKICAgIGluaXRpYWxpemVkID0gdHJ1ZTsKfQoKY2xhc3MgRGVyaXZlZDogcHVibGljIEJhc2UKewogICAgZnJpZW5kIGNsYXNzIEVuZm9yY2VyPERlcml2ZWQ+OwpwdWJsaWM6CiAgICB2b2lkIGluaXQoKSBvdmVycmlkZQogICAgewogICAgICAgIHN0ZDo6Y291dCA8PCAiQ2FsbGVkIGZyb20gZGVyaXZlZCFcbiI7CiAgICB9CnByaXZhdGU6CiAgICBEZXJpdmVkKCkKICAgIHsKICAgIH0KcHJpdmF0ZToKICAgIHVzaW5nIEJhc2VDbGFzcyA9IEJhc2U7CnByaXZhdGU6CiAgICBib29sIGluaXRpYWxpemVkID0gZmFsc2U7Cn07CgppbnQgbWFpbigpCnsKICAgIEVuZm9yY2VyPERlcml2ZWQ+IGQ7CiAgICBkLmluaXQoKTsKfQoK