#include <iostream>
#include <type_traits>
template<typename Derived>
struct base
{
void const_method() const
{
static_cast<Derived*>(this)->method();
}
void fixed_const_method() const
{
static_cast<
typename std::conditional<
std::is_const<
typename std::remove_pointer<decltype(this)>::type>::value,
Derived const* const,
Derived* const>::type>(this)->method();
}
};
struct derived : public base<derived>
{
void method() const
{
std::cout << "const method" << std::endl;
}
void method()
{
std::cout << "non-const method" << std::endl;
}
};
int main()
{
derived d;
d.fixed_const_method();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBEZXJpdmVkPgpzdHJ1Y3QgYmFzZQp7CiAgICB2b2lkIGNvbnN0X21ldGhvZCgpIGNvbnN0CiAgICB7CiAgICAgICAgc3RhdGljX2Nhc3Q8RGVyaXZlZCo+KHRoaXMpLT5tZXRob2QoKTsKICAgIH0KICAgIAogICAgdm9pZCBmaXhlZF9jb25zdF9tZXRob2QoKSBjb25zdAogICAgewogICAgICAgIHN0YXRpY19jYXN0PAogICAgICAgICAgICB0eXBlbmFtZSBzdGQ6OmNvbmRpdGlvbmFsPAogICAgICAgICAgICAgICAgc3RkOjppc19jb25zdDwKICAgICAgICAgICAgICAgICAgICB0eXBlbmFtZSBzdGQ6OnJlbW92ZV9wb2ludGVyPGRlY2x0eXBlKHRoaXMpPjo6dHlwZT46OnZhbHVlLAogICAgICAgICAgICAgICAgRGVyaXZlZCBjb25zdCogY29uc3QsCiAgICAgICAgICAgICAgICBEZXJpdmVkKiBjb25zdD46OnR5cGU+KHRoaXMpLT5tZXRob2QoKTsKICAgIH0KfTsKCnN0cnVjdCBkZXJpdmVkIDogcHVibGljIGJhc2U8ZGVyaXZlZD4KewogICAgdm9pZCBtZXRob2QoKSBjb25zdAogICAgewogICAgICAgIHN0ZDo6Y291dCA8PCAiY29uc3QgbWV0aG9kIiA8PCBzdGQ6OmVuZGw7CiAgICB9CgogICAgdm9pZCBtZXRob2QoKQogICAgewogICAgICAgIHN0ZDo6Y291dCA8PCAibm9uLWNvbnN0IG1ldGhvZCIgPDwgc3RkOjplbmRsOwogICAgfQp9OwoKaW50IG1haW4oKQp7CiAgICBkZXJpdmVkIGQ7CiAgICBkLmZpeGVkX2NvbnN0X21ldGhvZCgpOwogICAgCiAgICByZXR1cm4gMDsKfQ==