I noticed that the manual designation typedef on OuterClass too costly and sometimes leads to embarrassing errors. So I decided to make a copy-paste friendly typedef on OuterClass. Here's what I got:
#include <type_traits>
struct A{
typedef A NextOuterClass;
typedef A SelfClass;
struct B{
typedef NextOuterClass OuterClass;
typedef B NextOuterClass;
typedef B SelfClass;
struct C{
typedef NextOuterClass OuterClass;
typedef C NextOuterClass;
typedef C SelfClass;
};
};
};
#define CHECK(OWNER,TYPE)\
static_assert(\
std::is_same<OWNER::TYPE::OuterClass,OWNER>::value,\
#OWNER"::"#TYPE" - not ok"\
);
CHECK(A,B);
CHECK(A::B,C);
#undef CHECK
int main(){return 0;}
It works quite well, but not always:
#include <type_traits>
struct I{
typedef I NextOuterClass;
typedef I SelfClass;
};
struct D{
typedef D NextOuterClass;
typedef D SelfClass;
struct E:public I{
typedef NextOuterClass OuterClass; // NextOuterClass == I::NextOuterClass
typedef E NextOuterClass;
typedef E SelfClass;
typedef I ParentClass;
};
};
#define CHECK(OWNER,TYPE)\
static_assert(\
std::is_same<OWNER::TYPE::OuterClass,OWNER>::value,\
#OWNER"::"#TYPE" - not ok"\
);
CHECK(D,E); // D::E - not ok
#undef CHECK
int main(){return 0;}
If I remove the "typedef I NextOuterClass;", then it will work, but it is a bad decision because the class "I" may also have sub-classes:
#include <type_traits>
struct I{
typedef I NextOuterClass;
typedef I SelfClass;
struct G{
typedef NextOuterClass OuterClass;
typedef G NextOuterClass;
typedef G SelfClass;
};
};
struct D{
typedef D NextOuterClass;
typedef D SelfClass;
struct E:public I{
typedef NextOuterClass OuterClass; // NextOuterClass == I::NextOuterClass
typedef E NextOuterClass;
typedef E SelfClass;
typedef I ParentClass;
};
};
#define CHECK(OWNER,TYPE)\
static_assert(\
std::is_same<OWNER::TYPE::OuterClass,OWNER>::value,\
#OWNER"::"#TYPE" - not ok"\
);
CHECK(I,G);
CHECK(D,E); // D::E - not ok
#undef CHECK
int main(){return 0;}
I have tried to exploit the features of "private" and "template", but still has not reached the desired behavior.
In C++11 or C++14 have any reliable way to find OuterClass?
It would be nice to have such things here:
std::get_outer_class<T>::type
std::is_nested_class<T>::value