man*_*ler 16 c++ boost boost-propertytree
我已经阅读了boost :: property_tree的文档,但没有找到更新或合并ptree与另一个ptree的方法.我该怎么做呢?
鉴于下面的代码,update_ptree函数将如何?
#include <iostream>
#include <boost/property_tree/ptree.hpp>
using boost::property_tree::ptree;
class A
{
ptree pt_;
public:
void set_ptree(const ptree &pt)
{
pt_ = pt;
};
void update_ptree(const ptree &pt)
{
//How do I merge/update a ptree?
};
ptree get_ptree()
{
return pt_;
};
};
int main()
{
A a;
ptree pt;
pt.put<int>("first.number",0);
pt.put<int>("second.number",1);
pt.put<int>("third.number",2);
a.set_ptree(pt);
ptree pta = a.get_ptree();
//prints "0 1 2"
std::cout << pta.get<int>("first.number") << " "
<< pta.get<int>("second.number") << " "
<< pta.get<int>("third.number") << "\n";
ptree updates;
updates.put<int>("first.number",7);
a.update_ptree(updates);
pta = a.get_ptree();
//Because the update_tree function doesn't do anything it just prints "0 1 2".
//I would like to see "7 1 2"
std::cout << pta.get<int>("first.number") << " "
<< pta.get<int>("second.number") << " "
<< pta.get<int>("third.number") << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我已经考虑过迭代新的ptree并使用"put"来插入值.但是"put"需要一个类型,我不知道如何从新的ptree获取该信息并将其用作旧ptree的参数.
我在update_ptree函数中尝试过的一件事是使用:
pt_.add_child(".",pt);
Run Code Online (Sandbox Code Playgroud)
基本上我尝试将pt作为孩子添加到pt_的根目录.不幸的是,这似乎不起作用.
有任何想法吗?
我很感激任何帮助.
谢谢.
(我试图将标签property_tree和ptree添加到这个问题,但我不被允许)
J. *_*eja 17
我认为你必须以递归方式遍历property_tree.
您可以定义一个递归迭代每个节点的函数,并为每个节点调用一个方法:
template<typename T>
void traverse_recursive(const boost::property_tree::ptree &parent, const boost::property_tree::ptree::path_type &childPath, const boost::property_tree::ptree &child, T &method)
{
using boost::property_tree::ptree;
method(parent, childPath, child);
for(ptree::const_iterator it=child.begin();it!=child.end();++it) {
ptree::path_type curPath = childPath / ptree::path_type(it->first);
traverse_recursive(parent, curPath, it->second, method);
}
}
Run Code Online (Sandbox Code Playgroud)
我们可以定义一个更简单的函数来调用前一个函数:
template<typename T>
void traverse(const boost::property_tree::ptree &parent, T &method)
{
traverse_recursive(parent, "", parent, method);
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以修改类A,以便添加一个方法来合并一个节点并填充update_ptree方法:
#include <boost/bind.hpp>
class A {
ptree pt_;
public:
void set_ptree(const ptree &pt) {
pt_ = pt;
}
void update_ptree(const ptree &pt) {
using namespace boost;
traverse(pt, bind(&A::merge, this, _1, _2, _3));
}
ptree get_ptree() {
return pt_;
}
protected:
void merge(const ptree &parent, const ptree::path_type &childPath, const ptree &child) {
pt_.put(childPath, child.data());
}
};
Run Code Online (Sandbox Code Playgroud)
唯一的限制是可以使多个节点具有相同的路径.它们中的每一个都将被使用,但只有最后一个将被合并.
Boost.Property树不支持这个,但是:boost.org/doc/libs/1_48_0/doc/html/property_tree/appendices.html.看看未来的工作部分.
数学关系:ptree差异,联合,交集.
更新只是工会之后的差异. a = (a - b) + b.
一般解决方案需要递归遍历更新ptree并放置每个叶子.
但是,可以构建一个足够好的解决方案put_child.这可以满足您的所有需求,而无需一般解决方案的复杂性.
void merge( ptree& pt, const ptree& updates )
{
BOOST_FOREACH( auto& update, updates )
{
pt.put_child( update.first, update.second );
}
}
Run Code Online (Sandbox Code Playgroud)
足够好的解决方案有两个限制,巧合的是它们与ini_parser具有相同的限制.
| 归档时间: |
|
| 查看次数: |
8357 次 |
| 最近记录: |