【问题标题】:boost ptree failure with reverse iterators使用反向迭代器提升 ptree 失败
【发布时间】:2018-01-30 12:32:28
【问题描述】:

以下代码可以正常工作:

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

我该如何解决这个问题?

【问题讨论】:

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


    【解决方案1】:

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

    使用base()获取:

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

    但是BOOM无限循环!您在迭代时正在修改。这 never 很少是一个好主意。尽管iterator and reference stability 阻止了这实际上是未定义的行为,但在您的情况下,您碰巧在循环中不断找到相同的company 节点“next”。

    这是一个可预防的错误。

    不要试图“只输入break; 声明”。

    用正念的方式修复它:使用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

    【讨论】:

      猜你喜欢
      • 2015-12-16
      • 1970-01-01
      • 2010-10-27
      • 1970-01-01
      • 2017-12-28
      • 2017-05-27
      • 2017-03-10
      • 2017-01-20
      • 1970-01-01
      相关资源
      最近更新 更多