how to have user defined hash for unordered_map ?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • abir

    how to have user defined hash for unordered_map ?

    Hi,
    I want a user defined key for tr1 unordered_map.

    My classes are,
    template<typena me T>
    struct work{
    int count;
    work(int count) : count(count){}
    };
    template<typena me W>
    class worker{
    public:
    typedef worker<Wself_ty pe;
    worker(W& w,int pos) : w_(&w),pos_(pos ){}
    bool operator== (const self_type& other) const {
    assert(w_ == other.w_);
    return pos_ == other.pos_;
    }
    private:
    W* w_;
    int pos_;
    friend std::size_t hash(const self_type& self){
    return self.pos_ + w_->count;
    }
    };

    and want to have worker class as key to map.
    so calling is,
    typedef work<intWORK;
    typedef worker<WORKWORK ER;
    WORK w(2);
    WORKER w1(w,1);
    WORKER w2(w,2);
    WORKER w3(w,3);
    unordered_map<W ORKER,intm;
    m.insert(std::m ake_pair(w1,5)) ;

    i have == op for worker.and either declaring a hash_value or hash
    function is not working.
    how can i do it?

    thanks
    abir
  • Pete Becker

    #2
    Re: how to have user defined hash for unordered_map ?

    On 2008-07-11 01:05:57 -0400, abir <abirbasak@gmai l.comsaid:
    Hi,
    I want a user defined key for tr1 unordered_map.
    >
    My classes are,
    template<typena me T>
    struct work{
    int count;
    work(int count) : count(count){}
    };
    template<typena me W>
    class worker{
    public:
    typedef worker<Wself_ty pe;
    worker(W& w,int pos) : w_(&w),pos_(pos ){}
    bool operator== (const self_type& other) const {
    assert(w_ == other.w_);
    return pos_ == other.pos_;
    }
    private:
    W* w_;
    int pos_;
    friend std::size_t hash(const self_type& self){
    return self.pos_ + w_->count;
    }
    };
    >
    and want to have worker class as key to map.
    so calling is,
    typedef work<intWORK;
    typedef worker<WORKWORK ER;
    WORK w(2);
    WORKER w1(w,1);
    WORKER w2(w,2);
    WORKER w3(w,3);
    unordered_map<W ORKER,intm;
    m.insert(std::m ake_pair(w1,5)) ;
    >
    i have == op for worker.and either declaring a hash_value or hash
    function is not working.
    how can i do it?
    >
    unordered_map takes five template arguments, three of which have defaults:

    template <class Key, class T,
    class Hash = hash<Key>, class Pred = std::equal_to<K ey>,
    class Alloc = std::allocator< std::pair<const Key, T>>>
    class unordered_map;

    To provide your own hash object, use its type as the third argument. To
    provide your own equality predicate, use its type as the fourth
    argument. To provide your own allocator, use its type as the fifth
    argument.

    With just those changes, you'll get default-constructed versions of
    your hash type, equality type, and allocator type. If that's not
    appropriate, unordered_map has constructors that take objects of those
    types.

    --
    Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
    Standard C++ Library Extensions: a Tutorial and Reference
    (www.petebecker.com/tr1book)

    Comment

    • James Kanze

      #3
      Re: how to have user defined hash for unordered_map ?

      On Jul 11, 7:05 am, abir <abirba...@gmai l.comwrote:
      I want a user defined key for tr1 unordered_map.
      Pete Becker has given the reply to your question, but...
      template<typena me W>
      class worker{
      public:
      typedef worker<Wself_ty pe;
      worker(W& w,int pos) : w_(&w),pos_(pos ){}
      bool operator== (const self_type& other) const {
      assert(w_ == other.w_);
      Do you mean this? If so, the simplest way of ensuring it is to
      make w_ static.
      return pos_ == other.pos_;
      }
      private:
      W* w_;
      int pos_;
      friend std::size_t hash(const self_type& self){
      return self.pos_ + w_->count;
      }
      };
      --
      James Kanze (GABI Software) email:james.kan ze@gmail.com
      Conseils en informatique orientée objet/
      Beratung in objektorientier ter Datenverarbeitu ng
      9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

      Comment

      • abir

        #4
        Re: how to have user defined hash for unordered_map ?

        On Jul 11, 8:17 pm, James Kanze <james.ka...@gm ail.comwrote:
        On Jul 11, 7:05 am, abir <abirba...@gmai l.comwrote:
        >
          I want a user defined key for tr1 unordered_map.
        >
        Pete Becker has given the reply to your question, but...
        Previously i used unordered_map from boost, which automatically takes
        hash_value friend to compute hash, so i thought it is in the tr1
        standard.
        Now this works for tr1,
        unordered_map<W ORKER,int,boost ::hash<WORKER>m ;
        but for boost, this even works.
        unordered_map<W ORKER,intm;
        with,
        friend std::size_t hash_value(cons t self_type& self){
        return self.pos() + self.w().count;
        }
        I am still not sure why i cant just have a overloaded hash or some
        other function, and unordered_map automatically finds it like boost.
        Why i have to specify hash function for my class while i don't need
        for int, float ot string!
        There was some problem of const correctness in previous post, actually
        pos() & w() have to be const member function.
        >
        template<typena me W>
        class worker{
        public:
            typedef worker<Wself_ty pe;
            worker(W& w,int pos) : w_(&w),pos_(pos ){}
            bool operator== (const self_type& other) const {
                assert(w_ == other.w_);
        >
        Do you mean this?  If so, the simplest way of ensuring it is to
        make w_ static.
        >
                return pos_ == other.pos_;
            }
        Yes i mean this.
        w_ can't be static, as two worker can do different work.
        Two worker doing different work are not comparable and so are not
        allowed to form hash key for same container.
        private:
            W* w_;
            int pos_;
            friend std::size_t hash(const self_type& self){
                return self.pos_ + w_->count;
            }
        };
        >
        --
        James Kanze (GABI Software)             email:james.ka. ..@gmail.com
        Conseils en informatique orientée objet/
                           Beratung in objektorientier ter Datenverarbeitu ng
        9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
        Thanks
        abir

        Comment

        • Pete Becker

          #5
          Re: how to have user defined hash for unordered_map ?

          On 2008-07-11 14:48:47 -0400, abir <abirbasak@gmai l.comsaid:
          Why i have to specify hash function for my class while i don't need
          for int, float ot string!
          Because the tr1 library (as well as the C++0x library) provides hash
          objects for int, float, and string. It doesn't know anything about your
          type, so can't provide a hash object.

          --
          Pete
          Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
          Standard C++ Library Extensions: a Tutorial and Reference
          (www.petebecker.com/tr1book)

          Comment

          • Pete Becker

            #6
            Re: how to have user defined hash for unordered_map ?

            On 2008-07-11 16:42:11 -0400, Pete Becker <pete@versatile coding.comsaid:
            On 2008-07-11 14:48:47 -0400, abir <abirbasak@gmai l.comsaid:
            >
            >Why i have to specify hash function for my class while i don't need
            >for int, float ot string!
            >
            Because the tr1 library (as well as the C++0x library) provides hash
            objects for int, float, and string. It doesn't know anything about your
            type, so can't provide a hash object.
            Whoops, spoke too quickly. You can put your hash<MyClassin namespace
            std, and the unordered_map template will use it without you having to
            say so.

            --
            Pete
            Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
            Standard C++ Library Extensions: a Tutorial and Reference
            (www.petebecker.com/tr1book)

            Comment

            Working...