使用反向迭代器提升 ptree 失败
boost ptree failure with reverse iterators
以下代码可以正常工作:
#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <string>
using namespace boost::property_tree;
int main()
{
ptree root;
root.put("building.age", "42");
root.put("company.age", "32");
root.put("street.age", "19");
ptree attached_node;
attached_node.put("confirmed","yes");
attached_node.put("approved","yes");
for(auto it=root.begin();it!=root.end();++it)
{
std::cout
<< (it->first)
<< ": "
<< (it->second.get<std::string>("age"))
<< std::endl;
if(it->first=="company")
root.insert(it,make_pair("conditions",attached_node));
}
return 0;
}
但是,一旦我通过以下方式反向迭代:
for(auto it=root.rbegin();it!=root.rend();++it)
我遇到一个错误:
error: no matching function for call to ‘boost::property_tree::basic_ptree<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >::insert(boost::property_tree::basic_ptree<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >::reverse_iterator&, std::pair<const char*, boost::property_tree::basic_ptree<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> > >)’
root.insert(it,make_pair("conditions",attached_node));
^
我该如何解决这个问题?
那是因为插入函数没有采用反向迭代器。
使用base()
获取:
root.insert(it.base(), make_pair("conditions",attached_node));
但是BOOM:无限循环!您在迭代时正在修改。 从来没有 很少是个好主意。尽管 iterator and reference stability 阻止了这实际上是未定义的行为,但在您的情况下,您碰巧在循环中不断找到相同的 company
节点 "next"。
这是一个可以预防的错误。
不要被诱惑"just throw in a break;
statement"。
用正念的方式修复它:使用 CQS.
auto it = find_by_key(root.rbegin(), root.rend(), "company");
if (it != root.rend())
root.insert(it.base(), make_pair("conditions",attached_node));
看看变得多么干净! find_by_key
是对标准算法的简单包装:
template <typename It>
It find_by_key(It f, It l, std::string const& key) {
return std::find_if(f, l, [&](auto const& pair) {
//std::cout << pair.first << ": " << pair.second.get("age", "?") << "\n";
return pair.first == key;
});
}
如果没有调试的可能性,使用ptree
接口会更有效率:
auto it = root.equal_range("company").second;
if (it != root.not_found())
root.insert(root.to_iterator(it), make_pair("conditions",attached_node));
换句话说:
Algorithms, algorithms, algorithms.
灵感:"Never write a raw for loop" - Sean Parent
以下代码可以正常工作:
#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <string>
using namespace boost::property_tree;
int main()
{
ptree root;
root.put("building.age", "42");
root.put("company.age", "32");
root.put("street.age", "19");
ptree attached_node;
attached_node.put("confirmed","yes");
attached_node.put("approved","yes");
for(auto it=root.begin();it!=root.end();++it)
{
std::cout
<< (it->first)
<< ": "
<< (it->second.get<std::string>("age"))
<< std::endl;
if(it->first=="company")
root.insert(it,make_pair("conditions",attached_node));
}
return 0;
}
但是,一旦我通过以下方式反向迭代:
for(auto it=root.rbegin();it!=root.rend();++it)
我遇到一个错误:
error: no matching function for call to ‘boost::property_tree::basic_ptree<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >::insert(boost::property_tree::basic_ptree<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >::reverse_iterator&, std::pair<const char*, boost::property_tree::basic_ptree<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> > >)’
root.insert(it,make_pair("conditions",attached_node));
^
我该如何解决这个问题?
那是因为插入函数没有采用反向迭代器。
使用base()
获取:
root.insert(it.base(), make_pair("conditions",attached_node));
但是BOOM:无限循环!您在迭代时正在修改。 从来没有 很少是个好主意。尽管 iterator and reference stability 阻止了这实际上是未定义的行为,但在您的情况下,您碰巧在循环中不断找到相同的 company
节点 "next"。
这是一个可以预防的错误。
不要被诱惑"just throw in a break;
statement"。
用正念的方式修复它:使用 CQS.
auto it = find_by_key(root.rbegin(), root.rend(), "company");
if (it != root.rend())
root.insert(it.base(), make_pair("conditions",attached_node));
看看变得多么干净! find_by_key
是对标准算法的简单包装:
template <typename It>
It find_by_key(It f, It l, std::string const& key) {
return std::find_if(f, l, [&](auto const& pair) {
//std::cout << pair.first << ": " << pair.second.get("age", "?") << "\n";
return pair.first == key;
});
}
如果没有调试的可能性,使用ptree
接口会更有效率:
auto it = root.equal_range("company").second;
if (it != root.not_found())
root.insert(root.to_iterator(it), make_pair("conditions",attached_node));
换句话说:
Algorithms, algorithms, algorithms.
灵感:"Never write a raw for loop" - Sean Parent