【问题标题】:where is boost property_tree::empty_ptree?boost property_tree::empty_ptree 在哪里?
【发布时间】:2011-06-27 13:48:28
【问题描述】:

我正在使用 boots 的 property_tree 库。我正在寻找一种从ptree 对象获取子节点的方法,但如果失败则返回一个空的ptree。我在 property_tree/examples/empty_ptree_trick.cpp 中遇到了一个很好的例子:

void process_settings(const std::string &filename)
{
    ptree pt;
    read_info(filename, pt);    
    const ptree &settings = pt.get_child("settings", empty_ptree<ptree>());
    std::cout << "\n    Processing " << filename << std::endl;
    std::cout << "        Setting 1 is " << settings.get("setting1", 0) << std::endl;
    std::cout << "        Setting 2 is " << settings.get("setting2", 0.0) << std::endl;
    std::cout << "        Setting 3 is " << settings.get("setting3", "default") <<     std::endl;
}

这正是我需要的。问题是编译器抱怨empty_ptree() 函数不是boost:property_tree 的成员。 empty_ptree() 在哪里?

我在 VS2010 上使用 boost 1.44。

【问题讨论】:

    标签: boost-propertytree


    【解决方案1】:
    void process_settings(const std::string &filename)
    {
        ptree pt;
        read_info(filename, pt);    
        const ptree &settings = pt.get_child("settings", ptree());
        std::cout << "\n    Processing " << filename << std::endl;
        std::cout << "        Setting 1 is " << settings.get("setting1", 0) << std::endl;
        std::cout << "        Setting 2 is " << settings.get("setting2", 0.0) << std::endl;
        std::cout << "        Setting 3 is " << settings.get("setting3", "default") <<     std::endl;
    }
    

    注意,这将防止抛出 'boost::wrapexceptboost::property_tree::ptree_bad_path' 的实例

    【讨论】:

      【解决方案2】:

      我刚刚花了一整天的时间来回答这个问题!

      这是我的解决方案。首先我使用了指针,而不是引用,因为你必须立即初始化它们。然后我刚刚捕获了异常并添加了一个新的 ptree。

      using namespace boost::property_tree;
      
      ptree r_pt;
      ptree *c_pt;
      
      read_xml( "file.xml" , r_pt);
      
      try {
          c_pt = &(r_pt.get_child( "example" ));
      }
      catch (ptree_bad_path) {
          c_pt = &(r_pt.put_child( "example", ptree() ));
      }
      
      std::cout << "Setting 1 is " << c_pt.get("setting1", 0) << std::endl;
      

      据我所知,他们希望我们使用 boost::optional 类型。但我只是一个初学者..

      编辑 我刚刚找到了empty_ptree的实现。

      template<class Ptree>
          inline const Ptree &empty_ptree()
          {
              static Ptree pt;
              return pt;
          }
      

      我认为您可以将其添加到您的代码中并按照 empty_ptree_trick.cpp 中的说明使用它,但我现在坚持我的解决方案,直到我发现它实际上应该如何完成。

      【讨论】:

      • @expelleboy - 感谢您的努力:-)。但是,您建议的代码存在一些问题:1) read_xml 也可以抛出 - 因此您可能希望将其放在 try 块中。 2) 我不确定get_child 返回的 ptree 的生命周期是多少,但是 boost 中的示例总是从 get 分配结果,并且从不获取它们的地址。您最终可能会得到一个悬空指针。 3) 你可以跳过try-catch,因为get 的可选版本(你的catch 块中使用的那个),从不抛出。 4)返回对empty_ptree的引用比创建它更有效。
      • @bavaza np。实际上,我处理这些问题是通过创建一个我继承的类(代码中的 xml_branch)来强制我只在继承 xml_branch 的类或指向 ptree 的指针中创建实例。然后根类拥有实际的 ptree 及其指针。然后 root 处理成员 xml_branch 初始化时引发的所有异常。不幸的是,我无法向您展示完整的源代码,但我可以说这是一种相当优雅的方式。
      • 对不起,我的意思是说“分支处理所有异常 rais...”,但我似乎无法编辑我的评论..
      • 我也很好奇boost.org/doc/libs/1_55_0/libs/property_tree/examples/…中的empty_ptree是从哪里来的!
      • 好的,@expelledboy,你找到了实现——但是在哪个文件中?当我 grep 'empty_ptree' -r 在我的 $BOOST_ROOT 中有 11 次点击 - 大多数是 cmets 或文档,没有一个是实际的实现。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-10
      • 2012-09-14
      相关资源
      最近更新 更多