当前位置: 首页 > 知识库问答 >
问题:

使用 boost::hash with boost::p roperty_tree?

姬国安
2023-03-14

我正在尝试为包含提升::property_tree(提升::property_tree::basic_ptree

class MyClass{
public:
    friend std::size_t hash_value(const MyClass & obj);
private:
    boost::property_tree m_data;
}

inline std::size_t hash_value(const MyClass & obj){
    std::size_t seed = 0;
    boost::hash_combine(seed,obj.m_data);
    return seed;
}

此代码将无法编译为:“没有匹配函数用于调用'hash_value(const boost::p roperty_tree

我的问题:hash_value是不是在某个我没找到的头文件里为boost::property_tree定义的?如果不是,那么boost通过遍历property_tree来散列它的惯用方法是什么?

我应该使用ptree序列化转换为std::字符串和散列,还是手动遍历树并创建递归散列?


共有1个答案

韦阳晖
2023-03-14

只是专门化< code >散列

#include <boost/property_tree/ptree.hpp>
#include <boost/functional/hash.hpp>

namespace boost {
    template<typename Key, typename Data, typename KeyCompare>
    struct hash<boost::property_tree::basic_ptree<Key, Data, KeyCompare> > {
        size_t operator()(boost::property_tree::basic_ptree<Key, Data, KeyCompare> const& pt) const {
            std::size_t seed = 0;
            boost::hash_combine(seed, pt.template get_value<std::string>());
            boost::hash_range(seed, pt.begin(), pt.end());
            return seed;
        }
    };
}

够了!下面是一个小的 MyClass,它从类似 json 的文字中读取:

#include <boost/property_tree/json_parser.hpp>

class MyClass{
  public:
      MyClass(std::string const& json) {
          std::istringstream iss(json);
          read_json(iss, m_data);
      }
  private:
    boost::property_tree::ptree m_data;

    friend inline std::size_t hash_value(const MyClass& obj){
        std::size_t seed = 0;
        boost::hash_combine(seed, obj.m_data);
        return seed;
    }
};

现在,您可以对其进行测试

< kbd >在Coliru上直播

#include <iostream>

int main() {
    for (std::string const data : {
            R"({"a":[1,2,3],"b":{"nest":"hello","more":"world"}})",
            R"({"b":{"nest":"hello","more":"world"},"a":[1,2,3]})",
            R"({ })",
            R"({})",
        })
    {
        MyClass o(data);
        std::cout << "object hash: " << hash_value(o) << " " << data << "\n";
    }
}

印刷品:

object hash: 3573231694259656572 {"a":[1,2,3],"b":{"nest":"hello","more":"world"}}
object hash: 11176663460548092204 {"b":{"nest":"hello","more":"world"},"a":[1,2,3]}
object hash: 3864292196 { }
object hash: 3864292196 {}

对于许多容器,哈希

您可能想根据<code>ptree:

boost::hash_range(seed, pt.ordered_begin(), pt.not_found()); // CAUTION

这样做的优点是{a:1,“b:2}将与}{b:2,“a:1}匹配。

不要这样做,除非你知道你在做什么。具体来说,您需要向使用这个散列的每个容器/算法传递一个兼容的相等比较器。

如果您像这样编写它,并使用如下驱动程序进行测试:

int main() {
    MyClass a{ R"({"a":[1,2,3],"b":{"nest":"hello","more":"world"}})" },
            b{R"({"b":{"nest":"hello","more":"world"},"a":[1,2,3]})" },
            c{R"({ })" },
            d{R"({})" };

    for (auto& lhs : {a,b,c,d})
    for (auto& rhs : {a,b,c,d})
    {
        std::cout << "hash: " << hash_value(lhs) << " " << hash_value(rhs) << " - equality: " << std::boolalpha << (lhs==rhs) << "\n";
        if ((hash_value(lhs) == hash_value(rhs)) != (lhs==rhs))
            std::cout << " -- MISMATCH\n";
    }
}

它将打印:

hash: 10737438301360613971 10737438301360613971 - equality: true
hash: 10737438301360613971 10737438301360613971 - equality: false
 -- MISMATCH
hash: 10737438301360613971 3864292196 - equality: false
hash: 10737438301360613971 3864292196 - equality: false
hash: 10737438301360613971 10737438301360613971 - equality: false
 -- MISMATCH
hash: 10737438301360613971 10737438301360613971 - equality: true
hash: 10737438301360613971 3864292196 - equality: false
hash: 10737438301360613971 3864292196 - equality: false
hash: 3864292196 10737438301360613971 - equality: false
hash: 3864292196 10737438301360613971 - equality: false
hash: 3864292196 3864292196 - equality: true
hash: 3864292196 3864292196 - equality: true
hash: 3864292196 10737438301360613971 - equality: false
hash: 3864292196 10737438301360613971 - equality: false
hash: 3864292196 3864292196 - equality: true
hash: 3864292196 3864292196 - equality: true

不匹配警告表示相等和哈希不一致。

如果使用原始散列(折叠上方)运行测试驱动程序,它将打印:

hash: 3573231694259656572 3573231694259656572 - equality: true
hash: 3573231694259656572 11176663460548092204 - equality: false
hash: 3573231694259656572 3864292196 - equality: false
hash: 3573231694259656572 3864292196 - equality: false
hash: 11176663460548092204 3573231694259656572 - equality: false
hash: 11176663460548092204 11176663460548092204 - equality: true
hash: 11176663460548092204 3864292196 - equality: false
hash: 11176663460548092204 3864292196 - equality: false
hash: 3864292196 3573231694259656572 - equality: false
hash: 3864292196 11176663460548092204 - equality: false
hash: 3864292196 3864292196 - equality: true
hash: 3864292196 3864292196 - equality: true
hash: 3864292196 3573231694259656572 - equality: false
hash: 3864292196 11176663460548092204 - equality: false
hash: 3864292196 3864292196 - equality: true
hash: 3864292196 3864292196 - equality: true
 类似资料:
  • 我有一个这样的文件: [data.json] 如何通过解析此文件创建粒子向量。据我所知,我需要使用boop读取文件并将字符串(行)读入向量,然后解析向量的内容。 类粒子是这样的: 该类中省略了其他用于 get/set 的方法。 基本上,我想帮助创建一个

  • 根据http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/overview/cpp2011/futures.html,我们可以将boost::asio与一起使用。但是我找不到任何有关使用的信息,它具有更多的功能,例如。我怎么用?

  • Boost 库是一个经过千锤百炼、可移植、提供源代码的 C++ 库,作为标准库的后备,是 C++ 标准化进程的发动机之一。 Boost 库由 C++ 标准委员会库工作组成员发起,在 C++ 社区中影响甚大,其成员已近 2000 人。 Boost 库为我们带来了最新、最酷、最实用的技术,是不折不扣的“准”标准库。

  • 问题内容: 我试图将库包含在我的项目中,并且一直面临着同样的问题。我在使用Codeblocks IDE的Ubuntu 12.10上,尝试手动读取站点上的说明来安装库,但是在头文件以及使用前需要构建的库中出现错误。 然后,我通过terminalby安装了库。此后,在我的代码块程序中,可以包含类似的标题,但是当我尝试包含Filesystem库的标题( )时,出现以下错误: 我不确定如何解决此错误(特别

  • 我正试图将库包括在我的项目中,并一直面临着同样的问题。我在使用Codeblocks IDE的Ubuntu12.10上,尝试手动安装库,阅读网站上的说明,但在使用库之前,得到了带有标题的错误以及要构建的错误。 然后,我通过terminalby

  • 问题内容: 我在此处粘贴一些代码,这些代码使用boost iostream进行mmap并写入映射的文件: 当我在具有8个处理器和16GB RAM的centos 6机器上执行此操作时,我观察到以下内容: 当将数据插入到内存映射文件中时,RES(来自顶部命令)不断增加,直到14GB。我的印象是,当我映射文件时,VIRT将增加而不是RES。那么当我们写入mmap文件时,是先将其写入内存,然后再提交到磁盘