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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ssss1223ss/article/details/89281139

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 UnionKey来作为std::unordered_map的Key,UnionKey要特化std::hashstd::equal_to 这里提供一个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));
}

猜你喜欢

转载自blog.csdn.net/ssss1223ss/article/details/89281139