std::unordered_map如何使用不同类型的Key

std::unordered_map是c++11引入的关联容器,其HashMap特性和std::map的区别且不讨论,我们先看它的findcount方法:

iterator find( const Key& key );(1)	
iterator find( const Key& key, size_t hash );(1)	(C++20 起)
const_iterator find( const Key& key ) const;(2)	
const_iterator find( const Key& key, size_t hash ) const;(2)	(C++20 起)
template< class K > iterator find( const K& x );(3)	(C++20 起)
template< class K > iterator find( const K& x, size_t hash );(3)	(C++20 起)
template< class K > const_iterator find( const K& x ) const;(4)	(C++20 起)
template< class K > const_iterator find( const K& x, size_t hash ) const; 	(4)	(C++20 起)

size_type count( const Key& key ) const;(1)	(C++11 起)
size_type count( const Key& key, std::size_t hash ) const;(1)	(C++20 起)
template< class K > 
size_type count( const K& x ) const;(2)	(C++20 起)
template< class K > 
size_type count( const K& x, std::size_t hash ) const;(2)	(C++20 起)

问题是:c++20之前如何将其他类型作为Key来操作std::unordered_map呢?

我的方案是: 定义一个包含所有Key类型的tagged union,特化std::hashstd::equal_to,然后将其作为std::unordered_map的模板Key实参。 这里提供一个c++17 variant的实现版本。

#include <cassert>
#include <string_view>
#include <string>
#include <unordered_map>
#include <variant>

namespace std
{
template<typename ... Ts>
struct equal_to<std::variant<Ts...>>
{
    bool operator()(const std::variant<Ts...>& rhs, const std::variant<Ts...>& lhs) const
    {
        return std::visit([](auto && rhs, auto && lhs) { return rhs == lhs; }, rhs, lhs);
    }
};
}

template<typename V, typename ... K>
using Map = std::unordered_map<std::variant<K...>, V>;

int main()
{
    Map<int, std::string, std::string_view> m;

    using namespace std::string_view_literals;
    using namespace std::string_literals;

    m.insert({ "123"s, 123 });
    m.insert({ "abc"sv, 456 });
    m["123"sv] = 234;

    auto it = m.find("123"sv);
    assert(m.end() != it && it->second == 234);

    assert(1 == m.count("abc"s));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值