c++ - 以结构作为 boost::unordered_map 中的键的 boost 变体

标签 c++ boost unordered-map variant

我在 boost 变体中有两个结构,变体是 boost::unordered_map 的关键。我正在寻找实现哈希和等于方法的解决方案,该方法将采用变体结构。 下面是一个实现的 RouteHasher 方法(它在运行时不起作用(相同的键参数不会从映射中获取值)。如何实现一个将采用结构的两个成员作为哈希的哈希?

struct v4RouteKey_t
{
   uint8 ipv4[4];
   uint32 val;
}
struct v6RouteKey_t
{
   uint8 ipv6[16];
   uint32 val;
}
typedef boost::variant < v4RouteKey_t, v6RouteKey_t > RouteKey;
typedef boost::unordered_map < RouteKey, RouteValue_t > RouteMap;

struct RouteHasher : public boost::static_visitor<std::size_t>
{
    template<typename T>
    std::size_t operator()(const T& x) const { return boost::hash<T>()(x); }
    std::size_t operator()(const RouteKey& x) const { return 
    boost::apply_visitor(RouteHasher(), x); }
};

struct RouteEquals : public boost::static_visitor<bool>
{
    template<typename T>
    bool operator()(const T& lhs, const T& rhs) const { return lhs == rhs; }

    template<typename T1, typename T2>
    bool operator()(const T1& lhs, const T2& rhs) const { return false; }

    bool operator()(const RouteKey& lhs, const RouteKey& rhs) const
    { return boost::apply_visitor(RouteEquals(), lhs, rhs); }
};

最佳答案

您是否为 boost::hash_value 实现了哈希(std::hash<>v4RouteKey_t)和相等性和 v6RouteKey_t类型?

添加它可以为我编译:

Live On Coliru

#include <boost/unordered_map.hpp>
#include <boost/variant.hpp>
#include <boost/array.hpp>
#include <boost/tuple/tuple.hpp>
#include <cstdint>

struct v4RouteKey_t { 
    boost::array<uint8_t, 4> ipv4; uint32_t val; 
    bool operator==(v4RouteKey_t const& other) const {
        return ipv4 == other.ipv4 && val == other.val;
    };
};
struct v6RouteKey_t { 
    boost::array<uint8_t, 16> ipv6; uint32_t val; 
    bool operator==(v6RouteKey_t const& other) const {
        return ipv6 == other.ipv6 && val == other.val;
    };
};

size_t hash_value(v4RouteKey_t const& key) { return key.val; }
size_t hash_value(v6RouteKey_t const& key) { return key.val; }

struct RouteValue_t {};

typedef boost::variant<v4RouteKey_t, v6RouteKey_t> RouteKey;
typedef boost::unordered_map<RouteKey, RouteValue_t> RouteMap;

int main() {
    RouteMap map;
}

奖金

启用 c++17 的库/编译器可以在没有 boost 的情况下完成所有这些:

Live On Coliru

#include <unordered_map>
#include <numeric>
#include <variant>
#include <array>
#include <tuple>

struct v4RouteKey_t { 
    std::array<uint8_t, 4> ipv4; uint32_t val; 

    bool operator==(v4RouteKey_t const& other) const { return std::tie(ipv4, val) == std::tie(other.ipv4, other.val); };
};
struct v6RouteKey_t { 
    std::array<uint8_t, 16> ipv6; uint32_t val; 
    bool operator==(v6RouteKey_t const& other) const { return std::tie(ipv6, val) == std::tie(other.ipv6, other.val); };
};

namespace std {

    template <> struct hash<v4RouteKey_t> {
        size_t operator()(v4RouteKey_t const& key) { 
            return std::accumulate(key.ipv4.begin(), key.ipv4.end(), size_t(key.val), [](size_t seed, uint8_t b) { return (seed*139) ^ b; });
        }
    };
    template <> struct hash<v6RouteKey_t> {
        size_t operator()(v6RouteKey_t const& key) { 
            return std::accumulate(key.ipv6.begin(), key.ipv6.end(), size_t(key.val), [](size_t seed, uint8_t b) { return (seed*139) ^ b; });
        }
    };
}

struct RouteValue_t {};

typedef std::variant<v4RouteKey_t, v6RouteKey_t> RouteKey;
typedef std::unordered_map<RouteKey, RouteValue_t> RouteMap;

int main() {
    RouteMap map;
}

关于c++ - 以结构作为 boost::unordered_map 中的键的 boost 变体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46683847/

相关文章:

c++ - unordered_map 在分配或插入时出错

c++ - 等价于 C++ 中的 LinkedHashmap?

c++ - 使用 C++0x 的 unordered_map

c++ - 返回对父类 C++ 的引用

c++ - std::list 是否指向同一内存?

c++ - C++按有效位查找范围ip地址

c++ - boost enable_shared_from_this 功能是否会增加二进制文件的大小?

c++ - "templating"命名空间

c++ - 为什么在打印时忽略数字后面的 'string-like' 值?

c++ - 可移植线程 API