You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 03:40:21