C++中如何在编译期静态获取类的基类及基类直接子类?
编译期静态获取类的基类及基类直接子类的方案
给定如下继承结构:
class Base {}; class Derived1: public Base {}; class Derived2: public Derived1 {}; class Derived3: public Derived2 {};
std::is_base_of<Base, Derived3>可以判断Base是Derived3的基类,但有没有类似base_of<Derived3>的工具能直接得到Base类型?同时还想知道能否获取Base的直接子类,比如用base_child_of<Derived3>得到Derived1。
补充说明
下面是一个可行但不够优雅的实现,缺点是需要重复书写父类名称(例如class Derived2 : public Derived1 { HIERARCHY(Derived1) };),且未找到不影响多数IDE大括号显示的定义方式:
#include <iostream> #include <type_traits> #define HIERARCHY(PARENT) public: using inherited = PARENT; using base = inherited::base; class Base { public: using base = Base; }; class Derived1 : public Base { HIERARCHY(Base ) }; class Derived2 : public Derived1 { HIERARCHY(Derived1) }; class Derived3 : public Derived2 { HIERARCHY(Derived2) }; // 展开后等价于: // class Base { public: using base = Base; }; // class Derived1 : public Base { public: using inherited = Base; using base = inherited::base; }; // class Derived2 : public Derived1 { public: using inherited = Derived1; using base = inherited::base; }; // class Derived3 : public Derived2 { public: using inherited = Derived2; using base = inherited::base; }; // 现在CLASS::base已经可以直接用,这个结构体仅用于演示静态递归的实现方式 template <typename CLASS> struct base_of { using type = typename std::conditional< std::is_same<CLASS, Base>::value, CLASS, typename std::conditional< std::is_base_of<typename CLASS::base, CLASS>::value, typename base_of<typename CLASS::inherited>::type, CLASS >::type >::type; }; template<> struct base_of<Base> { using type = Base; }; template <typename CLASS> struct direct_child_of_base_of { using type = typename std::conditional< std::is_same<typename CLASS::inherited, typename CLASS::base>::value, CLASS, typename direct_child_of_base_of<typename CLASS::inherited>::type >::type; }; template<> struct direct_child_of_base_of<Base> { using type = void; }; int main() { std::cout << "base_of<Derived3>: " << typeid(base_of<Derived3>::type).name() << std::endl; std::cout << "base_of<Derived2>: " << typeid(base_of<Derived2>::type).name() << std::endl; std::cout << "base_of<Derived1>: " << typeid(base_of<Derived1>::type).name() << std::endl; std::cout << "base_of<Base >: " << typeid(base_of<Base >::type).name() << std::endl; std::cout << std::endl; // 以下写法和上面等价 std::cout << "Derived3::base: " << typeid(Derived3::base).name() << std::endl; std::cout << "Derived2::base: " << typeid(Derived2::base).name() << std::endl; std::cout << "Derived1::base: " << typeid(Derived1::base).name() << std::endl; std::cout << "Base ::base: " << typeid(Base ::base).name() << std::endl; std::cout << std::endl; std::cout << "direct_child_of_base_of<Derived3>: " << typeid(direct_child_of_base_of<Derived3>::type).name() << std::endl; std::cout << "direct_child_of_base_of<Derived2>: " << typeid(direct_child_of_base_of<Derived2>::type).name() << std::endl; std::cout << "direct_child_of_base_of<Derived1>: " << typeid(direct_child_of_base_of<Derived1>::type).name() << std::endl; std::cout << "direct_child_of_base_of<Base >: " << typeid(direct_child_of_base_of<Base >::type).name() << std::endl; return 0; }
GCC编译后的输出为:
base_of<Derived3>: 4Base base_of<Derived2>: 4Base base_of<Derived1>: 4Base base_of<Base >: 4Base Derived3::base: 4Base Derived2::base: 4Base Derived1::base: 4Base Base ::base: 4Base direct_child_of_base_of<Derived3>: 8Derived1 direct_child_of_base_of<Derived2>: 8Derived1 direct_child_of_base_of<Derived1>: 8Derived1 direct_child_of_base_of<Base >: v
内容的提问来源于stack exchange,提问作者Jacques
相关产品推荐
相关产品推荐

