【问题标题】:const yaml-cpp node changes when used multiple timesconst yaml-cpp 节点在多次使用时发生变化
【发布时间】:2018-08-20 11:55:36
【问题描述】:

对于 .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);

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

【问题讨论】:

  • 大概findNodeInYAMLTree(const YAML::Node node,应该是findNodeInYAMLTree(const YAML::Node&amp; node,
  • 也许将parentNodechildNode 更改为指针?我猜childNode = parentNode[childNodeName] 是将parentNode[childNodeName] 的内容复制到childNode 中,对于图书馆来说不是一件很友好的事情就是这样
  • 至于参考 YAML::Node &node 传递,无济于事。 YAML::Node 只不过是一个 bool 和两个指针而已。
  • 我没有设法写一个指针版本,因为“取临时地址”的编译器错误。 parentNode[childNodeName] 中的 operator[ ] 在该范围内创建一个 Node()。我想这不是要走的路,因为 parentNode[childNodeName] 是唯一可以更改输入数据的操作,但在使用指针时不会被替换。谢谢@AlanBirtles

标签: c++ yaml-cpp


【解决方案1】:

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

请致电Node::reset:

childNode.reset(parentNode[childNodeName]);

【讨论】:

  • 不直观。 true ;) 这可能需要更好的文档(doxygen api?),因为您的 lib 具有非常好的功能,但可用性有点落后。为在这里积极支持干杯。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多