使用反向迭代器提升ptree失败

时间:2017-08-22 09:34:36

标签: c++ c++11 boost iterator reverse-iterator

以下代码正常运行:

#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));
                                                         ^

如何解决此问题?

1 个答案:

答案 0 :(得分:5)

那是因为插入函数没有采用反向迭代器。

使用base()获取它:

enter image description here

root.insert(it.base(), make_pair("conditions",attached_node));

BOOM inifite循环!您在迭代时进行修改。这是永远很少是一个好主意。虽然iterator and reference stability阻止这实际上是未定义的行为,但在你的情况下,你碰巧找到了相同的company节点&#34; next&#34;在循环中。

这是一个可以预防的错误。

不要试图引用break;声明&#34;。

谨慎修复:使用CQS

<强> Live On Coliru

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接口会更有效:

<强> Live On Coliru

auto it = root.equal_range("company").second;
if (it != root.not_found())
    root.insert(root.to_iterator(it), make_pair("conditions",attached_node));

换句话说:

  

算法,算法,算法。

获取灵感:"Never write a raw for loop" - Sean Parent

enter image description here