#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;
}