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

如何用队列遍历含unique_ptr子节点的二叉树且避免移动对象?

问题解决

你的代码存在两个核心问题,导致编译错误或遍历逻辑失效:

1. 队列存储类型不合法

std::queue<std::unique_ptr<bsp_node>&> 这种写法不符合标准容器要求——队列无法直接存储引用类型(引用不满足容器元素的可拷贝/可移动语义)。由于你仅需要遍历树节点、不需要转移unique_ptr的所有权,直接存储原始指针bsp_node*即可,完全不会触发任何移动操作。

2. 遍历逻辑错误

循环中你一直判断Tree->Front和Tree->Back,这会导致永远只处理根节点的子节点,无法遍历整个树结构。正确的做法是使用当前出队的Node来访问其子节点。


修正后的代码:

struct bsp_node
{
    vec4 Plane;
    std::vector<polygon> Polygons;
    std::unique_ptr<bsp_node> Front;
    std::unique_ptr<bsp_node> Back;
};

uint32_t BSPGetIndexCount(const std::unique_ptr<bsp_node>& Tree)
{
    uint32_t Result = 0;
    // 改用原始指针队列,无需转移所有权
    std::queue<bsp_node*> BspQueue;
    if (Tree) {
        BspQueue.push(Tree.get());
    }

    uint32_t VertexIndex = 0;
    while(!BspQueue.empty())
    {
        bsp_node* Node = BspQueue.front();
        BspQueue.pop(); // 先执行pop,避免后续操作影响队列状态

        // 用const引用遍历多边形,避免不必要的拷贝
        for(const polygon& Poly : Node->Polygons)
        {
            Result += 3;
        }

        if(Node->Front != nullptr)
        {
            BspQueue.push(Node->Front.get());
        }

        if(Node->Back != nullptr)
        {
            BspQueue.push(Node->Back.get());
        }
    }

    return Result;
}

额外优化:遍历Polygons时使用const polygon&,避免对polygon对象的不必要拷贝,提升代码运行效率。

内容的提问来源于stack exchange,提问作者Zhukov Artem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 23:25:22