#include <iostream>
#include <type_traits>
#include <typeinfo>
template<typename Derived>
struct base
{
void const_method() const
{
static_cast<Derived*>(this)->method();
}
void fixed_const_method() const
{
// base<derived> const*
std::cout << typeid(this).name() << std::endl;
// base<derived>
std::cout << typeid(typename std::remove_pointer<decltype(this)>::type).name() << std::endl;
// base<derived>
std::cout << typeid(decltype(*this)).name() << std::endl;
// derived const*
std::cout << typeid(typename std::conditional<
std::is_const<
typename std::remove_pointer<decltype(this)>::type>::value,
Derived const* const,
Derived* const>::type).name() << std::endl;
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+CiNpbmNsdWRlIDx0eXBlaW5mbz4KCnRlbXBsYXRlPHR5cGVuYW1lIERlcml2ZWQ+CnN0cnVjdCBiYXNlCnsKICAgIHZvaWQgY29uc3RfbWV0aG9kKCkgY29uc3QKICAgIHsKICAgICAgICBzdGF0aWNfY2FzdDxEZXJpdmVkKj4odGhpcyktPm1ldGhvZCgpOwogICAgfQogICAgCiAgICB2b2lkIGZpeGVkX2NvbnN0X21ldGhvZCgpIGNvbnN0CiAgICB7CiAgICAgICAgLy8gYmFzZTxkZXJpdmVkPiBjb25zdCoKICAgICAgICBzdGQ6OmNvdXQgPDwgdHlwZWlkKHRoaXMpLm5hbWUoKSA8PCBzdGQ6OmVuZGw7CiAgICAgICAgLy8gYmFzZTxkZXJpdmVkPgogICAgICAgIHN0ZDo6Y291dCA8PCB0eXBlaWQodHlwZW5hbWUgc3RkOjpyZW1vdmVfcG9pbnRlcjxkZWNsdHlwZSh0aGlzKT46OnR5cGUpLm5hbWUoKSA8PCBzdGQ6OmVuZGw7CiAgICAgICAgLy8gYmFzZTxkZXJpdmVkPgogICAgICAgIHN0ZDo6Y291dCA8PCB0eXBlaWQoZGVjbHR5cGUoKnRoaXMpKS5uYW1lKCkgPDwgc3RkOjplbmRsOwogICAgICAgIC8vIGRlcml2ZWQgY29uc3QqCiAgICAgICAgc3RkOjpjb3V0IDw8IHR5cGVpZCh0eXBlbmFtZSBzdGQ6OmNvbmRpdGlvbmFsPAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6aXNfY29uc3Q8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVuYW1lIHN0ZDo6cmVtb3ZlX3BvaW50ZXI8ZGVjbHR5cGUodGhpcyk+Ojp0eXBlPjo6dmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVyaXZlZCBjb25zdCogY29uc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVyaXZlZCogY29uc3Q+Ojp0eXBlKS5uYW1lKCkgPDwgc3RkOjplbmRsOwogICAgICAgIAogICAgICAgIHN0YXRpY19jYXN0PAogICAgICAgICAgICB0eXBlbmFtZSBzdGQ6OmNvbmRpdGlvbmFsPAogICAgICAgICAgICAgICAgc3RkOjppc19jb25zdDwKICAgICAgICAgICAgICAgICAgICB0eXBlbmFtZSBzdGQ6OnJlbW92ZV9wb2ludGVyPGRlY2x0eXBlKHRoaXMpPjo6dHlwZT46OnZhbHVlLAogICAgICAgICAgICAgICAgRGVyaXZlZCBjb25zdCogY29uc3QsCiAgICAgICAgICAgICAgICBEZXJpdmVkKiBjb25zdD46OnR5cGU+KHRoaXMpLT5tZXRob2QoKTsKICAgIH0KfTsKCnN0cnVjdCBkZXJpdmVkIDogcHVibGljIGJhc2U8ZGVyaXZlZD4KewogICAgdm9pZCBtZXRob2QoKSBjb25zdAogICAgewogICAgICAgIHN0ZDo6Y291dCA8PCAiY29uc3QgbWV0aG9kIiA8PCBzdGQ6OmVuZGw7CiAgICB9CgogICAgdm9pZCBtZXRob2QoKQogICAgewogICAgICAgIHN0ZDo6Y291dCA8PCAibm9uLWNvbnN0IG1ldGhvZCIgPDwgc3RkOjplbmRsOwogICAgfQp9OwoKaW50IG1haW4oKQp7CiAgICBkZXJpdmVkIGQ7CiAgICBkLmZpeGVkX2NvbnN0X21ldGhvZCgpOwogICAgCiAgICByZXR1cm4gMDsKfQ==