zoukankan      html  css  js  c++  java
  • Boost.PropertyTree 在属性树里怎么访问数据

    在属性树里怎么访问数据?

     属性树类似于(几乎是)一个标准容器,其值类型为pair。它具有通常的成员函数,如insert、push_back、find、erase等,当然可以使用这些函数来填充和访问树。例如,下面的代码添加了关键词为“pi”的数据(几乎)等于数学pi值:

    1. ptree pt;
    2. pt.push_back(ptree::value_type("pi", ptree("3.14159")));
    为了求出pi的值,我们可以这样做:
    1. ptree::const_iterator it = pt.find("pi");
    2. double pi = boost::lexical_cast<double>(it->second.data());
    这里也要提示下:这里使用了一个非常好用的扩展类型转化,convert的库的函数:lexical_cast
     
    这看起来很麻烦,如果pi值不存储在树顶附近,我们会更关心错误。幸运的是,还有另一种正确的方法:
    1. ptree pt;
    2. pt.put("pi",3.14159);// put double
    3. double pi = pt.get<double>("pi");// get double
    没有比这更简单的了。基本上,有2个家庭成员函数,get和put,这允许直观地访问存储在树中的数据(直接的孩子或不是)。


    三种方式获取数据

     
    get有三个版本:get、get(默认值版本)和get_optional,这与失败处理策略不同。所有版本都使用路径说明符,它决定了在哪个键中搜索值。它可以是单个键,也可以是键的路径,其中路径元素以特殊字符(.)分隔。(如果没有具体说明)。例如debug.logging.errorlevel 可能是一个带点作为分隔符的有效路径。
     
    1.抛出异常的处理
    1. ptree pt;
    2. /* ... */
    3. float v = pt.get<float>("a.path.to.float.value");
     
    此调用将定位树中的适当节点,并尝试将其数据字符串转换为浮点值。如果失败,则抛出异常。如果路径不存在,它将是ptree_bad_path异常。如果值不能被翻译,它将是ptree_bad_data。它们都源于ptree_error,以使普通处理成为可能。
     
    2.有默认值的版本
    1. ptree pt;
    2. /* ... */
    3. float v = pt.get("a.path.to.float.value",-1.f);
    它将执行与上面相同的操作,但是如果失败,它将返回第二个参数指定的默认值(这里-1.f)而不是抛出。这在通常情况下是非常有用的,因为人们想要省略一些键。请注意,在这里通常没有必要的类型规范,因为类型是由默认值参数决定的。
     
    3.可选的版本
    1. ptree pt;
    2. /* ... */
    3. boost::optional<float> v = pt.get_optional<float>("a.path.to.float.value");
    这个版本使用boost::optional来处理提取失败。在成功的提取上,它将返回boost::optional的初始化值。否则,它将返回未初始化的boost::optional

    要从这棵树(不是一些子键)中检索值,可以使用get_value、get_value (default-value version)和get_value_optional。它们具有相同的语义以获得函数,但它们不接受路径参数。不要调用get和empty路径,因为它将尝试以空名称提取子键的内容。
     
    如果要使用除默认之外的分隔,您需要显式地构造路径对象。
    ptree的路径类型是string_path实例化,因此最容易引用它的方法是ptree::path_type。
    这样你就可以使用在他们的key上有(.)的树【也就是,key里有点的路径】:
    1. typedef ptree::path_type path;
    2. pt.get<float>(path("p.a.t.h/t.o/v.a.l.u.e",'/'));
    3. pt.get(path("p.a.t.h/t.o/v.a.l.u.e",'/'),0, NULL);
    4. pt.get_optional<std::string>(path("p.a.t.h/t.o/v.a.l.u.e",'/'));
    可以看到,这里使用的是"/"来作为分隔符,原因,很简单,你在key你有了点(.),就不能再使用点来作为分隔了,我们需要使用新的字符!
     
    注意:在PropertyTree的预发布版本中存在的get和get_optional的特殊重载已被删除。这是因为重载与使用每个调用的数据转换器冲突。
        

    Two Ways of Putting Data

    同样的道理,有获得值,就有添加值!get和put是一对,在添加数据时不需要处理丢失的值。如果提供的值不能转换为树的数据类型,则函数将抛出ptree_bad_data
    1. ptree pt;
    2. pt.put("a.path.to.float.value",3.14f);
    3. // Overwrites the value
    4. pt.put("a.path.to.float.value",2.72f);
    5. // Adds a second node with the new value.
    6. pt.add("a.path.to.float.value",3.14f);
     
    调用put将在指定的路径中插入一个新值,以便调用来指定相同的路径将检索它。
    此外,在路径遍历过程中,put将插入任何丢失的路径元素。例如,调用put("key1.key2.key3", 3.14f),在一个空的树上,
    将插入三个新子:
    key1, 
    key1.key2; 
    key1.key2.key3。
    最后一个将接收到一个字符串“3.14”作为数据,而前两个将会有空的数据字符串。总是在现有序列的后面插入新的键

    put和add之间的区别是,put将覆盖现有的值,如果有的话,add将创建一个新的节点来保存该值,即使指定的路径引用了现有的节点
    与get_value类似,还有一个put_value函数。它不接受路径:
    ptree pt;
    pt.put_value(3.14f);
  • 相关阅读:
    82.Java集合学习之Collections与Arrays
    81.Java集合之TreeMap
    vuex 封装
    async awiat
    纯前端导入导出
    使用node搭建服务器
    node.js
    axios请求拦截器
    数据结构学习第十九天
    数据结构学习第十八天
  • 原文地址:https://www.cnblogs.com/xujintao/p/8325941.html
Copyright © 2011-2022 走看看