#include <iostream>
#include <type_traits>

enum class Mutability {Const, Non_Const};

template<Mutability T>
struct ConstMutability: std::true_type{};

template<>
struct ConstMutability<Mutability::Non_Const>: std::false_type{};

template <typename T, Mutability U>
class Obj
{
public:
    template <Mutability V, typename std::enable_if<
    std::is_same<ConstMutability<U>, ConstMutability<V>>::value || 
    (ConstMutability<V>::value && !ConstMutability<U>::value)
    >::type* = nullptr>
    class Ref
    {
    public:
        Ref() {std::cout << "Successfully created a Ref object" << std::endl;}

        friend class Obj;
    };

    Obj() {}
};


int main()
{
    Obj<int, Mutability::Const>::Ref<Mutability::Const> test1; //pass
    //Obj<int, Mutability::Const>::Ref<Mutability::Non_Const> test2; // fail
    Obj<int, Mutability::Non_Const>::Ref<Mutability::Const> test3; // pass
    Obj<int, Mutability::Non_Const>::Ref<Mutability::Non_Const> test4; // pass
}