C ++:提升ptree相对密钥

时间:2017-07-22 14:07:27

标签: c++ c++11 boost boost-propertytree ptree

在使用ptree中的boost的C ++中,我需要找到从a.b.c2.e1访问a.b的相对密钥。此密钥为c2.e1。如何编写一个找到该相对密钥的函数?

#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

using namespace boost::property_tree;

std::string relative_key(const ptree &p1,const ptree &p2)
{
    ??????????????
    // return "b.c2.e1";
}

int main()
{
    ptree pt0;

    pt0.put("a.b.c1",4);
    pt0.put("a.b.c2.e1",4);
    pt0.put("a.b.c4",4);
    pt0.put("a.d",4);
    pt0.put("k.m",4);
    pt0.put("k.n",4);

    ptree &pt_e1=pt0.get_child("a.b.c2.e1");
    ptree &pt_b=pt0.get_child("a.b");

    std::cout<<relative_key(pt_e1,pt_b)<<std::endl;

    return 0;
}

1 个答案:

答案 0 :(得分:1)

您需要编写递归搜索功能,例如:

bool find_subtree_helper(ptree const& haystack, ptree const& needle, path_type& path) {
    if (std::addressof(haystack) == std::addressof(needle))
        return true;

    for (auto& child : haystack) {
        auto next = path;
        next /= child.first;

        if ( std::addressof(child.second) == std::addressof(needle) 
          || find_subtree_helper(child.second, needle, next))
        {
            path = next;
            return true;
        }
    }

    return false;
}

path_type find_subtree(ptree const& haystack, ptree const& needle) {
    path_type path;

    if (!find_subtree_helper(haystack, needle, path))
        throw std::range_error("not subtree");

    return path;
}

使用它像:

<强> Live On Coliru

path_type p = find_subtree(pt_b, pt_e1);
std::cout << p.dump() << std::endl;

打印“c2.e1”。

完整列表

<强> Live On Coliru

#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

using namespace boost::property_tree;

using path_type = ptree::path_type;

bool find_subtree_helper(ptree const& haystack, ptree const& needle, path_type& path) {
    if (std::addressof(haystack) == std::addressof(needle))
        return true;

    for (auto& child : haystack) {
        auto next = path;
        next /= child.first;

        if ( std::addressof(child.second) == std::addressof(needle) 
          || find_subtree_helper(child.second, needle, next))
        {
            path = next;
            return true;
        }
    }

    return false;
}

path_type find_subtree(ptree const& haystack, ptree const& needle) {
    path_type path;

    if (!find_subtree_helper(haystack, needle, path))
        throw std::range_error("not subtree");

    return path;
}

int main()
{
    ptree pt0;

    pt0.put("a.b.c1",4);
    pt0.put("a.b.c2.e1",4);
    pt0.put("a.b.c4",4);
    pt0.put("a.d",4);
    pt0.put("k.m",4);
    pt0.put("k.n",4);

    ptree &pt_e1 = pt0.get_child("a.b.c2.e1");
    ptree &pt_b  = pt0.get_child("a.b");

    path_type p = find_subtree(pt_b, pt_e1);
    std::cout << p.dump() << std::endl;
}