如何用队列遍历含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
相关产品推荐
相关产品推荐

