c++ 如何使用具有对象向量的元素的unordered_set

栏目: C++ · 发布时间: 6年前

内容简介:http://stackoverflow.com/questions/19655733/how-to-use-unordered-set-that-has-elements-that-are-vector-of-pairint-int

我想要这样的东西

unordered_set<vector<pair<int,int>>> us;

但即使没有对:

#include <vector>
#include <unordered_set>
using namespace std;

int main() {
    unordered_set<vector<int>> um;
}

它失败:

In file included from /usr/include/c++/4.8/bits/hashtable.h:35:0,
                 from /usr/include/c++/4.8/unordered_set:47,
                 from prog.cpp:2:
/usr/include/c++/4.8/bits/hashtable_policy.h: In instantiation of ‘struct std::__detail::_Hash_code_base<std::vector<int>, std::vector<int>, std::__detail::_Identity, std::hash<std::vector<int> >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, true>’:
/usr/include/c++/4.8/bits/hashtable_policy.h:1402:10:   required from ‘struct std::__detail::_Hashtable_base<std::vector<int>, std::vector<int>, std::__detail::_Identity, std::equal_to<std::vector<int> >, std::hash<std::vector<int> >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Hashtable_traits<true, true, true> >’
/usr/include/c++/4.8/bits/hashtable.h:174:11:   required from ‘class std::_Hashtable<std::vector<int>, std::vector<int>, std::allocator<std::vector<int> >, std::__detail::_Identity, std::equal_to<std::vector<int> >, std::hash<std::vector<int> >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, true, true> >’
/usr/include/c++/4.8/bits/unordered_set.h:96:18:   required from ‘class std::unordered_set<std::vector<int> >’
prog.cpp:7:32:   required from here
/usr/include/c++/4.8/bits/hashtable_policy.h:1070:12: error: invalid use of incomplete type ‘struct std::hash<std::vector<int> >’
     struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2,
            ^
In file included from /usr/include/c++/4.8/bits/stl_bvector.h:1134:0,
                 from /usr/include/c++/4.8/vector:65,
                 from prog.cpp:1:
/usr/include/c++/4.8/bits/functional_hash.h:58:12: error: declaration of ‘struct std::hash<std::vector<int> >’
     struct hash;
            ^
In file included from /usr/include/c++/4.8/bits/hashtable.h:35:0,
                 from /usr/include/c++/4.8/unordered_set:47,
                 from prog.cpp:2:
/usr/include/c++/4.8/bits/hashtable_policy.h:1070:12: error: invalid use of incomplete type ‘struct std::hash<std::vector<int> >’
     struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2,
            ^
In file included from /usr/include/c++/4.8/bits/stl_bvector.h:1134:0,
                 from /usr/include/c++/4.8/vector:65,
                 from prog.cpp:1:
/usr/include/c++/4.8/bits/functional_hash.h:58:12: error: declaration of ‘struct std::hash<std::vector<int> >’
     struct hash;
            ^
In file included from /usr/include/c++/4.8/bits/hashtable.h:35:0,
                 from /usr/include/c++/4.8/unordered_set:47,
                 from prog.cpp:2:
/usr/include/c++/4.8/bits/hashtable_policy.h:1082:53: error: invalid use of incomplete type ‘struct std::hash<std::vector<int> >’
       using __ebo_h1 = _Hashtable_ebo_helper<1, _H1>;
                                                     ^
In file included from /usr/include/c++/4.8/bits/stl_bvector.h:1134:0,
                 from /usr/include/c++/4.8/vector:65,
                 from prog.cpp:1:
/usr/include/c++/4.8/bits/functional_hash.h:58:12: error: declaration of ‘struct std::hash<std::vector<int> >’
     struct hash;
            ^
In file included from /usr/include/c++/4.8/bits/hashtable.h:35:0,
                 from /usr/include/c++/4.8/unordered_set:47,
                 from prog.cpp:2:
/usr/include/c++/4.8/bits/hashtable_policy.h:1082:53: error: invalid use of incomplete type ‘struct std::hash<std::vector<int> >’
       using __ebo_h1 = _Hashtable_ebo_helper<1, _H1>;
                                                     ^
In file included from /usr/include/c++/4.8/bits/stl_bvector.h:1134:0,
                 from /usr/include/c++/4.8/vector:65,
                 from prog.cpp:1:
/usr/include/c++/4.8/bits/functional_hash.h:58:12: error: declaration of ‘struct std::hash<std::vector<int> >’
     struct hash;
            ^
prog.cpp: In constructor ‘std::unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(std::unordered_set<_Value, _Hash, _Pred, _Alloc>::size_type, const hasher&, const key_equal&, const allocator_type&) [with _Value = std::vector<int>; _Hash = std::hash<std::vector<int> >; _Pred = std::equal_to<std::vector<int> >; _Alloc = std::allocator<std::vector<int> >; std::unordered_set<_Value, _Hash, _Pred, _Alloc>::size_type = unsigned int; std::unordered_set<_Value, _Hash, _Pred, _Alloc>::hasher = std::hash<std::vector<int> >; std::unordered_set<_Value, _Hash, _Pred, _Alloc>::key_equal = std::equal_to<std::vector<int> >; std::unordered_set<_Value, _Hash, _Pred, _Alloc>::allocator_type = std::allocator<std::vector<int> >]’:
prog.cpp:7:32: error: invalid use of incomplete type ‘std::unordered_set<std::vector<int> >::hasher {aka struct std::hash<std::vector<int> >}’
     unordered_set<vector<int>> um;
                                ^
In file included from /usr/include/c++/4.8/bits/stl_bvector.h:1134:0,
                 from /usr/include/c++/4.8/vector:65,
                 from prog.cpp:1:
/usr/include/c++/4.8/bits/functional_hash.h:58:12: error: declaration of ‘std::unordered_set<std::vector<int> >::hasher {aka struct std::hash<std::vector<int> >}’
     struct hash;
            ^
prog.cpp:7:32: note:   when instantiating default argument for call to std::unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(std::unordered_set<_Value, _Hash, _Pred, _Alloc>::size_type, const hasher&, const key_equal&, const allocator_type&) [with _Value = std::vector<int>; _Hash = std::hash<std::vector<int> >; _Pred = std::equal_to<std::vector<int> >; _Alloc = std::allocator<std::vector<int> >; std::unordered_set<_Value, _Hash, _Pred, _Alloc>::size_type = unsigned int; std::unordered_set<_Value, _Hash, _Pred, _Alloc>::hasher = std::hash<std::vector<int> >; std::unordered_set<_Value, _Hash, _Pred, _Alloc>::key_equal = std::equal_to<std::vector<int> >; std::unordered_set<_Value, _Hash, _Pred, _Alloc>::allocator_type = std::allocator<std::vector<int> >]
     unordered_set<vector<int>> um;
                                ^
In file included from /usr/include/c++/4.8/bits/hashtable.h:35:0,
                 from /usr/include/c++/4.8/unordered_set:47,
                 from prog.cpp:2:
/usr/include/c++/4.8/bits/hashtable_policy.h: In instantiation of ‘std::__detail::_Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, std::__detail::_Default_ranged_hash, true>::_Hash_code_base(const _ExtractKey&, const _H1&, const _H2&, const std::__detail::_Default_ranged_hash&) [with _Key = std::vector<int>; _Value = std::vector<int>; _ExtractKey = std::__detail::_Identity; _H1 = std::hash<std::vector<int> >; _H2 = std::__detail::_Mod_range_hashing]’:
/usr/include/c++/4.8/bits/hashtable_policy.h:1463:65:   required from ‘std::__detail::_Hashtable_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, _Hash, _Traits>::_Hashtable_base(const _ExtractKey&, const _H1&, const _H2&, const _Hash&, const _Equal&) [with _Key = std::vector<int>; _Value = std::vector<int>; _ExtractKey = std::__detail::_Identity; _Equal = std::equal_to<std::vector<int> >; _H1 = std::hash<std::vector<int> >; _H2 = std::__detail::_Mod_range_hashing; _Hash = std::__detail::_Default_ranged_hash; _Traits = std::__detail::_Hashtable_traits<true, true, true>]’
/usr/include/c++/4.8/bits/hashtable.h:828:24:   required from ‘std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::_Hashtable(std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::size_type, const _H1&, const _H2&, const _Hash&, const _Equal&, const _ExtractKey&, const allocator_type&) [with _Key = std::vector<int>; _Value = std::vector<int>; _Alloc = std::allocator<std::vector<int> >; _ExtractKey = std::__detail::_Identity; _Equal = std::equal_to<std::vector<int> >; _H1 = std::hash<std::vector<int> >; _H2 = std::__detail::_Mod_range_hashing; _Hash = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<true, true, true>; std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::size_type = unsigned int; std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::allocator_type = std::allocator<std::vector<int> >]’
/usr/include/c++/4.8/bits/hashtable.h:397:26:   required from ‘std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::_Hashtable(std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::size_type, const _H1&, const key_equal&, const allocator_type&) [with _Key = std::vector<int>; _Value = std::vector<int>; _Alloc = std::allocator<std::vector<int> >; _ExtractKey = std::__detail::_Identity; _Equal = std::equal_to<std::vector<int> >; _H1 = std::hash<std::vector<int> >; _H2 = std::__detail::_Mod_range_hashing; _Hash = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<true, true, true>; std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::size_type = unsigned int; std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::key_equal = std::equal_to<std::vector<int> >; std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::allocator_type = std::allocator<std::vector<int> >]’
/usr/include/c++/4.8/bits/unordered_set.h:136:35:   required from ‘std::unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(std::unordered_set<_Value, _Hash, _Pred, _Alloc>::size_type, const hasher&, const key_equal&, const allocator_type&) [with _Value = std::vector<int>; _Hash = std::hash<std::vector<int> >; _Pred = std::equal_to<std::vector<int> >; _Alloc = std::allocator<std::vector<int> >; std::unordered_set<_Value, _Hash, _Pred, _Alloc>::size_type = unsigned int; std::unordered_set<_Value, _Hash, _Pred, _Alloc>::hasher = std::hash<std::vector<int> >; std::unordered_set<_Value, _Hash, _Pred, _Alloc>::key_equal = std::equal_to<std::vector<int> >; std::unordered_set<_Value, _Hash, _Pred, _Alloc>::allocator_type = std::allocator<std::vector<int> >]’
prog.cpp:7:32:   required from here
/usr/include/c++/4.8/bits/hashtable_policy.h:1099:63: error: invalid use of incomplete type ‘struct std::hash<std::vector<int> >’
       : __ebo_extract_key(__ex), __ebo_h1(__h1), __ebo_h2(__h2) { }
                                                               ^
In file included from /usr/include/c++/4.8/bits/stl_bvector.h:1134:0,
                 from /usr/include/c++/4.8/vector:65,
                 from prog.cpp:1:
/usr/include/c++/4.8/bits/functional_hash.h:58:12: error: declaration of ‘struct std::hash<std::vector<int> >’
     struct hash;
            ^
In file included from /usr/include/c++/4.8/bits/hashtable.h:35:0,
                 from /usr/include/c++/4.8/unordered_set:47,
                 from prog.cpp:2:
/usr/include/c++/4.8/bits/hashtable_policy.h:1099:63: error: invalid use of incomplete type ‘struct std::hash<std::vector<int> >’
       : __ebo_extract_key(__ex), __ebo_h1(__h1), __ebo_h2(__h2) { }
                                                               ^
In file included from /usr/include/c++/4.8/bits/stl_bvector.h:1134:0,
                 from /usr/include/c++/4.8/vector:65,
                 from prog.cpp:1:
/usr/include/c++/4.8/bits/functional_hash.h:58:12: error: declaration of ‘struct std::hash<std::vector<int> >’
     struct hash;
            ^

http://ideone.com/wusr5V

你可以这样实现,基于boost :: hash_combine来理清哈希的计算:
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <unordered_set>

namespace
{
    // a little helper that should IMHO be standardized
    template<typename T>
    std::size_t make_hash(const T& v)
    {
        return std::hash<T>()(v);
    }

    // adapted from boost::hash_combine
    void hash_combine(std::size_t& h, const std::size_t& v)
    {
        h ^= v + 0x9e3779b9 + (h << 6) + (h >> 2);
    }

    // hash any container
    template<typename T>
    struct hash_container
    {
        size_t operator()(const T& v) const
        {
            size_t h=0;
            for( const auto& e : v ) {
                hash_combine(h, make_hash(e));
            }
            return h;
        }
    };
}

namespace std
{
    // support for pair<T,U> if T and U can be hashed
    template<typename T, typename U>
    struct hash<pair<T, U>>
    {
        size_t operator()(const pair<T,U>& v) const
        {
            size_t h=make_hash(v.first);
            hash_combine(h, make_hash(v.second));
            return h;
        }
    };

    // support for vector<T> if T is hashable
    // (the T... is a required trick if the vector has a non-standard allocator)
    template<typename... T>
    struct hash<vector<T...>> : hash_container<vector<T...>> {};

    // the same for map<T,U> if T and U are hashable
    template<typename... T>
    struct hash<map<T...>> : hash_container<map<T...>> {};

    // simply add more containers as needed
}

int main()
{
    std::unordered_set<std::vector<std::pair<int,int>>> us;
    us.insert(std::vector<std::pair<int,int>>{{{42,0},{17,64}}});
    std::cout << us.size() << std::endl;
    std::cout << us.begin()->size() << std::endl;
    std::cout << us.begin()->begin()->first << std::endl;

    std::unordered_set<std::map<int,int>> usm;
    std::map<int,int> m{{42,0},{17,64}};
    usm.insert(m);
}

Live example

注意,当Clang与libstdc组合时,有一个 problem ,当专门的std :: hash可能会影响你.已经用GCC 4.8.2修复了,但Coliru仍然是 visible .如果这是您的案例中的问题,您可以使用-Wno-mismatchatched标签禁用警告,而Clang将会在 no longer complain .

http://stackoverflow.com/questions/19655733/how-to-use-unordered-set-that-has-elements-that-are-vector-of-pairint-int


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Flexible Rails

Flexible Rails

Peter Armstrong / Manning Publications / 2008-01-23 / USD 44.99

Rails is a fantastic tool for web application development, but its Ajax-driven interfaces stop short of the richness you gain with a tool like Adobe Flex. Simply put, Flex is the most productive way t......一起来看看 《Flexible Rails》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

URL 编码/解码
URL 编码/解码

URL 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具