如何通过索引向量访问未知深度嵌套node类的对应子元素?
核心问题分析
你的原有实现存在3个关键错误:
- 语法不合法:
node elementRef = &nodeObject是将node*指针赋值给node实例,类型完全不匹配,编译无法通过 - C++引用不可重绑定:引用一旦初始化就不能再指向其他对象,不能作为循环中游标跟踪当前节点,必须用指针实现
- 原有
operator[]返回值是副本:每次调用都会生成独立的临时节点,和原树中的节点没有关联,无法实现导航效果,必须改为返回左值引用
修复后的node类实现
#include <vector> #include <variant> #include <stdexcept> #include <string> class node { public: // 非const版本:返回左值引用,指向原树中的节点 node& operator[](unsigned int index) { if (index >= children.size()) { throw std::out_of_range("子节点索引超出范围"); } if (!std::holds_alternative<node>(children[index])) { throw std::runtime_error("当前子节点为字符串类型,无法继续向下索引"); } return std::get<node>(children[index]); } // const版本:适配const修饰的node对象访问 const node& operator[](unsigned int index) const { if (index >= children.size()) { throw std::out_of_range("子节点索引超出范围"); } if (!std::holds_alternative<node>(children[index])) { throw std::runtime_error("当前子节点为字符串类型,无法继续向下索引"); } return std::get<node>(children[index]); } // 获取指定位置的子元素,支持直接访问字符串类型的叶子节点 std::variant<node, std::string>& get_child(unsigned int index) { if (index >= children.size()) { throw std::out_of_range("子节点索引超出范围"); } return children[index]; } const std::variant<node, std::string>& get_child(unsigned int index) const { if (index >= children.size()) { throw std::out_of_range("子节点索引超出范围"); } return children[index]; } // 辅助接口:添加子节点,可根据实际需求调整 void add_child(const node& child) { children.emplace_back(child); } void add_child(const std::string& child) { children.emplace_back(child); } private: std::vector<std::variant<node, std::string>> children; };
索引向量导航实现
// 非const版本导航:返回最终位置的元素引用 std::variant<node, std::string>& navigate(node& root, const std::vector<unsigned int>& indices) { if (indices.empty()) { throw std::invalid_argument("索引向量不能为空"); } // 用指针跟踪当前节点,支持循环中修改指向 node* current = &root; // 遍历前n-1个索引,导航到倒数第二层节点 for (size_t i = 0; i < indices.size() - 1; ++i) { current = &(*current)[indices[i]]; } // 返回最后一级的目标元素 return current->get_child(indices.back()); } // const版本导航:适配const根节点访问 const std::variant<node, std::string>& navigate(const node& root, const std::vector<unsigned int>& indices) { if (indices.empty()) { throw std::invalid_argument("索引向量不能为空"); } const node* current = &root; for (size_t i = 0; i < indices.size() - 1; ++i) { current = &(*current)[indices[i]]; } return current->get_child(indices.back()); }
使用示例
#include <iostream> int main() { // 构造测试树结构 node root; node level1, level2, level3; level3.add_child("最终目标内容"); level2.add_child(level3); // 给level1填充4个空节点,第5个位置(索引4)放level2 for (int i = 0; i < 4; ++i) level1.add_child(node{}); level1.add_child(level2); // 给root第1个位置(索引0)放level1 root.add_child(level1); // 等价于 root[0][4][0][0] 访问 std::vector<unsigned int> indices = {0, 4, 0, 0}; auto& res = navigate(root, indices); if (std::holds_alternative<std::string>(res)) { std::cout << std::get<std::string>(res) << std::endl; // 输出:最终目标内容 } return 0; }
内容的提问来源于stack exchange,提问作者Clayton Gearhart
相关产品推荐
相关产品推荐

