【问题标题】:boost property_tree issues getting valuesboost property_tree 获取值的问题
【发布时间】:2018-09-25 15:44:36
【问题描述】:

这是我对 boost::property_tree 的第一次体验,我找不到一种方法来重现按照文档 (How to Access Data in a Property Tree) 从树中获取值的方法。这是我为试验属性树而编写的简单代码:

#include <iostream>
#include <string>

#include <boost/property_tree/info_parser.hpp>
#include <boost/property_tree/ptree.hpp>

namespace pt = boost::property_tree;

int main(int argc, char *argv[]) {
  pt::ptree tree;

  tree.put("pi", 3.14159);
  tree.put("name", "John Doe");

  for (auto &[key, value] : tree)
    std::cout << key << " : " << value.get_value<std::string>() << "\n";

  std::cout << "pi : " << tree.get_value("pi") << "\n";
  std::cout << "name : " << tree.get_value("name") << "\n";

  auto pi = tree.get_optional<float>("pi").get();
  std::cout << "pi optional : " << pi << "\n";

  auto pi_found = tree.find("pi");
  std::cout << "pi found : " << pi_found->second.data() << "\n";

  // the commented line doesn't compile
  // std::cout << "not found : " << tree.get_value<int>("null") << "\n";

  std::cout << "not found : " << tree.get_value("null") << "\n";

  // the line below causes an assertion error:
  // Assertion failed: (this->is_initialized()), function get, file /usr/local/include/boost/optional/optional.hpp, line 1191.
  // not found : Abort trap: 6
  std::cout << "not found : " << tree.get_optional<int>("null").get() << "\n";

  pt::write_info("ptree.info", tree);

  return 0;
}

这是输出:

pi : 3.1415899999999999
name : John Doe
pi :
name :
pi optional : 3.14159
pi found : 3.1415899999999999
not found :

可以看出tree.get_value("whatever") 没有返回值,tree.get_value("null") 不会抛出异常,get_optional&lt;whatever type&gt; 不会编译。我的实验的行为与文档中所述的完全不同。排除导致断言错误的行会按预期创建输出信息文件。

我的环境是:

MacOS 10.11.6
macbrew installed tools and libraries
boost 1.67
clang 7.0
meson build system

【问题讨论】:

    标签: c++ boost boost-propertytree


    【解决方案1】:

    您可以将 ptree 绘制为:

    node1 is tree (has 2 children, data() of tree is "")
     |
     |- (node2) pi ----> data=3.14...
     |
     |- (node3) name --> data="Joe Doe"
    

    [1]

    可以看出 tree.get_value("whatever") 没有返回值

    tree 是节点,有 2 个子节点(pi,名称)。 打电话时

    tree.get_value(defaultValue) // you are not passing PATH, but DEFAULT VALUE
    

    上面一行被翻译成

    tree.get_child("").get_value(defaultValue)
    

    所以,"" 路径存在,因为它是到 tree 节点的路径,并且 tree.data() 返回 "" - 此路径的空字符串。所以defaultValue 无法打印,您会看到空字符串作为输出。 你应该只为孩子调用get_value(在调用这个方法之前在tree上使用get_child,它在boost参考中有描述),get_value的参数是默认值。所以替换

      std::cout << "pi : " << tree.get_child("pi").get_value("PI is 4.0") << "\n";
      std::cout << "name : " << tree.get_child("name").get_value("noname") << "\n";
    

    你会看到3.14Joe Doe

    [2]

    tree.get_value("null") 不会抛出异常

    在 [1] 点中有描述。 "" 路径存在,并且此路径的 data() 为空字符串。所以你看不到 null 字符串作为默认值。

    [3]

    // 注释行无法编译 // std::cout

    这一行无法编译,因为ptree类没有那个方法,我想你要调用这个方法:

      template<typename Type> 
      unspecified get_value(const Type & default_value) const;
    

    您将Type定义为intint作为函数模板参数涉及默认值只能是int,而不是字符串。

    【讨论】:

    • 在你的问题中你放了boost参考的链接,在这个页面上没有使用get_value,只是提到了这个功能,但是有一句很重要的Don't call get with and empty path to do this as it will try to extract contents of subkey with empty name. -> get_value() == get_child("").get_value()看到这个页面boost.org/doc/libs/1_65_1/boost/property_tree/ptree.hpp
    • 嗨@rafix07,非常感谢你的回答。 lib 文档与您显示的内容大不相同。例如,从有关如何获取值的页面中指出:float v = pt.get&lt;float&gt;("a.path.to.float.value"); 它具有误导性,并且与 lib 的实际工作方式不对应。关于您的建议,以下工作:std::cout &lt;&lt; "pi : " &lt;&lt; tree.get_child("pi").get_value&lt;double&gt;() &lt;&lt; "\n";
    • 你是对的,我从 for 循环中取出 get_value 并毫不担心地粘贴了它。这是要走的路tree.get&lt;float&gt;("pi")
    【解决方案2】:

    我的错,我没有使用tree.get&lt;float&gt;("pi"),而是复制并粘贴了用于不同用途的tree.get_value&lt;float&gt;("pi")。在@rafix07 评论的帮助下回答了这个问题。 get&lt;type&gt;("key path") 是正确的使用方法。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-04
    • 2013-09-24
    • 1970-01-01
    • 2013-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-15
    相关资源
    最近更新 更多