const yaml-cpp 节点多次使用时会发生变化

const yaml-cpp node changes when used multiple times

对于 .yaml,说

aaa:
    bbb:
        ccc: testOne
        ddd: testTwo

目标是找到给定参数路径的值,例如aaa/bbb/ccc。当我尝试这样做两次时,尽管传递了一个 const YAML::Node ,但父 aaa 已更改并指向我上次搜索的位置。 我知道 YAML::Nodes 只是一个浅层结构,因此我的操作显然正在改变底层数据。在不更改输入数据的情况下浏览树的巧妙方法是什么?

有关更多详细信息,请参阅我的带有一些调试输出的最小示例:

std::string findNodeInYAMLTree(const YAML::Node node, const std::vector<std::string> &pathInTree)
{
    std::cout << "Input root node for findNodeInYAMLTree():" << std::endl;
    for (const auto& kv : node) {
        std::cout << kv.first.as<std::string>() << "\n";
    }

    YAML::Node parentNode = node;
    YAML::Node childNode = parentNode;
    std::vector<std::string>::const_iterator it = pathInTree.begin();
    while (it != pathInTree.end()) {
        std::string childNodeName = *it;
        if (!parentNode.IsDefined() || !parentNode[childNodeName]) {
            std::cout << "Did not find the next tree path node <" << childNodeName << ">" << std::endl;
            return "Failure";
        }
        childNode = parentNode[childNodeName];
        parentNode = childNode;
        it++;
    }
    return childNode.as<std::string>();
}

void testSameFctTwice()
{
    YAML::Node aaa;
    YAML::Node node = YAML::Load("aaa: {bbb: {ccc: testOne, ddd: testTwo}}");
    std::vector<std::string> testOneStr({"aaa", "bbb","ccc"});
    std::cout << findNodeInYAMLTree(node, testOneStr) << std::endl;
    std::vector<std::string> testTwoStr({"aaa", "bbb", "ddd"});
    std::cout << findNodeInYAMLTree(node, testTwoStr) << std::endl;
}

我使用的是system-repo的0.5.2版本,暂时将yaml-cpp更新为0.6/HEAD并没有改变。

输出将是:

Input root node for findNodeInYAMLTree():
aaa
testOne
Input root node for findNodeInYAMLTree():
ddd
ccc
Did not find the next tree path node <aaa>
Failure

所以解决方法是:

    YAML::Node parentNode = YAML::Clone(node);

但我觉得这可以做得更好。

在yaml-cpp中,operator =分配了一个参考值。这有点不直观;请参阅 this issue 讨论问题。

而是调用 Node::reset:

childNode.reset(parentNode[childNodeName]);