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

在类型树中查找最近祖先类型的技术实现问询

实现 nearest_ancestor 类型特性

针对你构建的类型树,我们可以通过提取父类型、递归遍历父链的方式实现需求:找到从根节点到目标节点路径上,紧邻根节点的下一级节点(即目标节点的祖先链中,父节点为根的那个节点)。

1. 提取节点的父类型

首先定义parent_type特性,用于从Node派生类中提取其父类型参数:

#include <type_traits>

// 前置声明Node类
template <typename T, typename PARENT, typename ... CHILDREN>
class Node;

// 基础模板:非Node派生类触发编译错误
template <typename T>
struct parent_type {
    static_assert(std::is_base_of_v<Node<T, void>, T>, "T must be a class derived from Node");
};

// 特化模板:提取Node的PARENT参数
template <typename T, typename PARENT, typename... CHILDREN>
struct parent_type<Node<T, PARENT, CHILDREN...>> {
    using type = PARENT;
};

// 辅助别名,简化类型引用
template <typename T>
using parent_type_t = typename parent_type<T>::type;

2. 验证后代关系(可选)

为了避免传入非后代类型导致的无意义递归,定义is_descendant特性判断一个类型是否是另一个的后代(含自身):

// 判断Descendant是否是Ancestor的后代
template <typename Descendant, typename Ancestor>
struct is_descendant {
    static constexpr bool value = std::is_same_v<Descendant, Ancestor> || 
                                  (!std::is_same_v<parent_type_t<Descendant>, void> && is_descendant<parent_type_t<Descendant>, Ancestor>::value);
};

template <typename Descendant, typename Ancestor>
constexpr bool is_descendant_v = is_descendant<Descendant, Ancestor>::value;

3. 实现 nearest_ancestor 特性

通过递归遍历目标节点的父链,直到找到父节点为根节点的节点,该节点即为所求:

// 基础模板声明
template <typename Root, typename Descendant, typename = void>
struct nearest_ancestor;

// 边界情况:目标节点就是根节点时,返回void(可根据需求自定义)
template <typename Root>
struct nearest_ancestor<Root, Root> {
    using type = void;
};

// 终止条件:当前节点的父节点是根节点,返回当前节点
template <typename Root, typename Descendant>
struct nearest_ancestor<Root, Descendant, std::enable_if_t<std::is_same_v<parent_type_t<Descendant>, Root>>> {
    using type = Descendant;
};

// 递归情况:当前节点的父不是根节点,继续向上遍历父链
template <typename Root, typename Descendant>
struct nearest_ancestor<Root, Descendant, std::enable_if_t<!std::is_same_v<parent_type_t<Descendant>, Root> && !std::is_same_v<Descendant, Root>>> {
    static_assert(is_descendant_v<Descendant, Root>, "Descendant must be a descendant of Root");
    
    using type = typename nearest_ancestor<Root, parent_type_t<Descendant>>::type;
};

// 辅助别名,简化类型引用
template <typename Root, typename Descendant>
using nearest_ancestor_t = typename nearest_ancestor<Root, Descendant>::type;

测试验证

结合你的类型树进行测试,以下断言均会通过:

// 你的类型树定义
template <typename T, typename PARENT, typename ... CHILDREN>
class Node {};

class X;
class A;
class AA;
class AB;
class B;
class BA;
class BB;

class X : public Node<X, void, A, B> {};
class A : public Node<A, X, AA, AB> {};
class AA : public Node<AA, A> {};
class AB : public Node<AB, A> {};
class B : public Node<B, X, BA, BB> {};
class BA : public Node<BA, B> {};
class BB : public Node<BB, B> {};

// 测试用例
static_assert(std::is_same_v<nearest_ancestor_t<X, BB>, B>, "BB's nearest ancestor relative to X is B");
static_assert(std::is_same_v<nearest_ancestor_t<X, A>, A>, "A's nearest ancestor relative to X is A");
static_assert(std::is_same_v<nearest_ancestor_t<A, AA>, AA>, "AA's nearest ancestor relative to A is AA");
static_assert(std::is_same_v<nearest_ancestor_t<X, X>, void>, "X's nearest ancestor relative to X is void");

内容的提问来源于stack exchange,提问作者Patrick Wright

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 14:30:52