#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
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CgplbnVtIGNsYXNzIE11dGFiaWxpdHkge0NvbnN0LCBOb25fQ29uc3R9OwoKdGVtcGxhdGU8TXV0YWJpbGl0eSBUPgpzdHJ1Y3QgQ29uc3RNdXRhYmlsaXR5OiBzdGQ6OnRydWVfdHlwZXt9OwoKdGVtcGxhdGU8PgpzdHJ1Y3QgQ29uc3RNdXRhYmlsaXR5PE11dGFiaWxpdHk6Ok5vbl9Db25zdD46IHN0ZDo6ZmFsc2VfdHlwZXt9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIE11dGFiaWxpdHkgVT4KY2xhc3MgT2JqCnsKcHVibGljOgogICAgdGVtcGxhdGUgPE11dGFiaWxpdHkgViwgdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8CiAgICBzdGQ6OmlzX3NhbWU8Q29uc3RNdXRhYmlsaXR5PFU+LCBDb25zdE11dGFiaWxpdHk8Vj4+Ojp2YWx1ZSB8fCAKICAgIChDb25zdE11dGFiaWxpdHk8Vj46OnZhbHVlICYmICFDb25zdE11dGFiaWxpdHk8VT46OnZhbHVlKQogICAgPjo6dHlwZSogPSBudWxscHRyPgogICAgY2xhc3MgUmVmCiAgICB7CiAgICBwdWJsaWM6CiAgICAgICAgUmVmKCkge3N0ZDo6Y291dCA8PCAiU3VjY2Vzc2Z1bGx5IGNyZWF0ZWQgYSBSZWYgb2JqZWN0IiA8PCBzdGQ6OmVuZGw7fQoKICAgICAgICBmcmllbmQgY2xhc3MgT2JqOwogICAgfTsKCiAgICBPYmooKSB7fQp9OwoKCmludCBtYWluKCkKewogICAgT2JqPGludCwgTXV0YWJpbGl0eTo6Q29uc3Q+OjpSZWY8TXV0YWJpbGl0eTo6Q29uc3Q+IHRlc3QxOyAvL3Bhc3MKICAgIC8vT2JqPGludCwgTXV0YWJpbGl0eTo6Q29uc3Q+OjpSZWY8TXV0YWJpbGl0eTo6Tm9uX0NvbnN0PiB0ZXN0MjsgLy8gZmFpbAogICAgT2JqPGludCwgTXV0YWJpbGl0eTo6Tm9uX0NvbnN0Pjo6UmVmPE11dGFiaWxpdHk6OkNvbnN0PiB0ZXN0MzsgLy8gcGFzcwogICAgT2JqPGludCwgTXV0YWJpbGl0eTo6Tm9uX0NvbnN0Pjo6UmVmPE11dGFiaWxpdHk6Ok5vbl9Db25zdD4gdGVzdDQ7IC8vIHBhc3MKfQ==