C++ unordered_map fail when used with a vector as key

后端 未结 2 742
太阳男子
太阳男子 2020-12-05 05:03

Background: I am comming from the Java world and I am fairly new to C++ or Qt.

In order to play with unordered_map, I have written the following simple program:

<
2条回答
  •  天命终不由人
    2020-12-05 05:52

    §23.2.5, paragraph 3, says:

    Each unordered associative container is parameterized by Key, by a function object type Hash that meets the Hash requirements (17.6.3.4) and acts as a hash function for argument values of type Key, and by a binary predicate Pred that induces an equivalence relation on values of type Key.

    Using vector as Key and not providing explicit hash and equivalence predicate types means the default std::hash> and std::equal_to> will be used.

    The std::equal_to for the equivalence relation is fine, because there is an operator == for vectors, and that's what std::equal_to uses.

    There is however, no std::hash> specialization, and that's probably what the linker error you didn't show us says. You need to provide your own hasher for this to work.

    An easy way of writing such an hasher is to use boost::hash_range:

    template  // we can make this generic for any container [1]
    struct container_hash {
        std::size_t operator()(Container const& c) const {
            return boost::hash_range(c.begin(), c.end());
        }
    };
    

    Then you can use:

    std::unordered_map> map;
    

    Of course, if you need different equality semantics in the map you need to define the hash and equivalence relation appropriately.


    1. However, avoid this for hashing unordered containers, as different orders will produce different hashes, and the order in unordered container is not guaranteed.

提交回复
热议问题