[英]C++: boost ptree remove children: no matching function
In an attempt to remove children of a boost property tree, I use a direct node in erase
function which lead to为了删除 boost 属性树的子节点,我在
erase
函数中使用了一个直接节点,这导致
error: no matching function for call to
‘boost::property_tree::basic_ptree<std::__cxx11::basic_string<char>,
std::__cxx11::basic_string<char> >::erase(std::pair<const
std::__cxx11::basic_string<char>,
boost::property_tree::basic_ptree<std::__cxx11::basic_string<char>,
std::__cxx11::basic_string<char> > >&)’
at在
pt0.erase(pt_child);
What is the correct form of the code?代码的正确形式是什么?
#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
using namespace boost::property_tree;
void print(const ptree &p)
{
json_parser::write_json(std::cout, p);
}
int main()
{
ptree pt0;
for(int i=0;i<10;i++)
pt0.put_child("kid"+std::to_string(i+1),ptree());
print(pt0);
for(auto& pt_child : pt0)
pt0.erase(pt_child);
print(pt0);
return 0;
}
You could do this:ptree.get_child("path.to").erase("child");你可以这样做:ptree.get_child("path.to").erase("child"); Note that this deletes ALL nodes named "child" within the path "path.to" and their subchildren.
请注意,这会删除路径“path.to”及其子子节点中名为“child”的所有节点。
It's unfortunate but the ptree
api doesn't have a remove_child
method that works with a property_tree::path
just like it does for get_child
.不幸的是,
ptree
api 没有remove_child
方法可以像get_child
一样与property_tree::path
get_child
。 Here's a small method that does that though.不过,这里有一个小方法可以做到这一点。 The important part is that you can use the dot notation to specify whatever subchild you want to remove.
重要的部分是您可以使用点表示法来指定要删除的任何子子项。 Also this implementation only removes a single child.
此外,此实现仅删除一个子项。
#include <boost/property_tree/ptree.hpp>
#include <boost/algorithm/string.hpp>
// TODO: this should support boost::property_tree::path
// like get_child does to make it obvious that it supports
// the path separator notation for specifying sub children
bool remove_child(boost::property_tree::ptree& pt, const std::string& path) {
// split up the path into each sub part
std::vector<std::string> path_parts;
boost::split(path_parts, path, boost::is_any_of("."));
// check each part of the path
auto* root = &pt;
for (const auto& part : path_parts) {
// if we dont have this sub child bail
auto found = root->find(part);
if (found == root->not_found())
return false;
// if this was the last one to look for remove it
if (&part == &path_parts.back()) {
root->erase(root->to_iterator(found));
}// next sub child
else {
root = &found->second;
}
}
// made it to the last sub child without bailing on not found
return true;
}
According to docs you can only .erase
by key_type
or by iterator
, but you are trying to do it by value_type
.根据文档只能
.erase
通过key_type
或iterator
,但你试图通过做value_type
。
You can do either do你可以做
for(auto& [key, data]: pt0)
pt0.erase(key);
or loop over iterators explicitly:或显式循环迭代器:
for(auto it = pt0.begin(); it != pt0.end(); ++it)
pt0.erase(it);
But since you are removing all children anyway, a better way would be to just但是既然你要移除所有的孩子,更好的方法是
pt0.clear();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.