#include <iostream>
using namespace std;
template <typename Derived> struct base
{
void interface()
{
static_cast<Derived*>(this)->implementation();
}
void implementation()
{
cout << "Default\n";
}
};
struct overrider : base<overrider>
{
void implementation()
{
cout << "Overridden\n";
}
};
struct nonoverrider : base<nonoverrider>
{
};
template <typename twicederived> struct derived : base<twicederived>
{
void implementation()
{
cout << "Derived Base\n";
}
};
struct twicederivednonoverrider : derived<twicederivednonoverrider>
{
};
struct twicederivedoverrider : derived<twicederivedoverrider>
{
void implementation()
{
cout << "Derived overridden\n";
}
};
int main()
{
overrider overrider;
nonoverrider nonoverrider;
twicederivednonoverrider twicederivednonoverrider;
twicederivedoverrider twicederivedoverrider;
overrider.interface();
nonoverrider.interface();
twicederivednonoverrider.interface();
twicederivedoverrider.interface();
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnRlbXBsYXRlIDx0eXBlbmFtZSBEZXJpdmVkPiBzdHJ1Y3QgYmFzZQp7CiAgdm9pZCBpbnRlcmZhY2UoKQogIHsKICAgIHN0YXRpY19jYXN0PERlcml2ZWQqPih0aGlzKS0+aW1wbGVtZW50YXRpb24oKTsKICB9CiAgdm9pZCBpbXBsZW1lbnRhdGlvbigpCiAgewogICAgY291dCA8PCAiRGVmYXVsdFxuIjsKICB9Cn07CiAKc3RydWN0IG92ZXJyaWRlciA6IGJhc2U8b3ZlcnJpZGVyPgp7CiAgdm9pZCBpbXBsZW1lbnRhdGlvbigpCiAgewogICAgY291dCA8PCAiT3ZlcnJpZGRlblxuIjsKICB9Cn07CgpzdHJ1Y3Qgbm9ub3ZlcnJpZGVyIDogYmFzZTxub25vdmVycmlkZXI+CnsKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSB0d2ljZWRlcml2ZWQ+IHN0cnVjdCBkZXJpdmVkIDogYmFzZTx0d2ljZWRlcml2ZWQ+IAp7CiAgdm9pZCBpbXBsZW1lbnRhdGlvbigpCiAgewogICAgY291dCA8PCAiRGVyaXZlZCBCYXNlXG4iOwogIH0KfTsKCnN0cnVjdCB0d2ljZWRlcml2ZWRub25vdmVycmlkZXIgOiBkZXJpdmVkPHR3aWNlZGVyaXZlZG5vbm92ZXJyaWRlcj4Kewp9OwoKc3RydWN0IHR3aWNlZGVyaXZlZG92ZXJyaWRlciA6IGRlcml2ZWQ8dHdpY2VkZXJpdmVkb3ZlcnJpZGVyPgp7CiAgdm9pZCBpbXBsZW1lbnRhdGlvbigpCiAgewogICAgY291dCA8PCAiRGVyaXZlZCBvdmVycmlkZGVuXG4iOwogIH0KfTsKCmludCBtYWluKCkKewogIG92ZXJyaWRlciBvdmVycmlkZXI7CiAgbm9ub3ZlcnJpZGVyIG5vbm92ZXJyaWRlcjsKICB0d2ljZWRlcml2ZWRub25vdmVycmlkZXIgdHdpY2VkZXJpdmVkbm9ub3ZlcnJpZGVyOwogIHR3aWNlZGVyaXZlZG92ZXJyaWRlciB0d2ljZWRlcml2ZWRvdmVycmlkZXI7CgogIG92ZXJyaWRlci5pbnRlcmZhY2UoKTsKICBub25vdmVycmlkZXIuaW50ZXJmYWNlKCk7CiAgdHdpY2VkZXJpdmVkbm9ub3ZlcnJpZGVyLmludGVyZmFjZSgpOwogIHR3aWNlZGVyaXZlZG92ZXJyaWRlci5pbnRlcmZhY2UoKTsKfQo=