Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将boost::hash与boost::property_树一起使用?_Boost_Hash_Boost Propertytree - Fatal编程技术网

将boost::hash与boost::property_树一起使用?

将boost::hash与boost::property_树一起使用?,boost,hash,boost-propertytree,Boost,Hash,Boost Propertytree,我试图为包含boost::property_树(boost::property_树::basic_树)的对象生成哈希值。在boost头文件中搜索属性树时,我找不到任何定义的哈希值函数。我正在努力实现的基本示例: class MyClass{ public: friend std::size_t hash_value(const MyClass & obj); private: boost::property_tree m_data; } inline std::size

我试图为包含boost::property_树(
boost::property_树::basic_树)的对象生成哈希值。在boost头文件中搜索属性树时,我找不到任何定义的哈希值函数。我正在努力实现的基本示例:

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::property_tree&')”

我的问题是:在我没有找到的某个头文件中是否为boost::property_树定义了hash_值。如果不是,那么通过遍历属性树散列属性树的boost惯用方法是什么


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

只需为ptree专门化
hash

#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;
        }
    };
}
现在你可以测试它了

#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";
    }
}
注意:散列和相等 对于许多容器,hash假设一个对应的相等比较器。如果他们不匹配,你会被解雇

您可能会试图根据
ptree
的有序(关联)接口定义
hash\u范围:

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

不要使用序列化,因为它容易更改表示/松散信息。刚刚意识到您只能使用ptree专门化(通过boost,而不是)。我根据您的答案使用了一个实现,然后在其中发现了一个bug。回到您的答案,我能够在您提供的示例中重现错误:。当前的实现没有检查ptree中项目的值,只检查键。@Carter12s您完全正确。令人尴尬的是,我忘记了节点可以有子节点以外的“内容”值。固定的。你是C++的上帝!我刚刚自己想出了解决办法,但你已经抢先一步了。谢谢你的帮助。有小费罐吗?
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