简体   繁体   中英

unable to find key in unordered_map

Created an unordered_map with key as a shared_ptr of a class. Defined a hash function that created hash based on a data member of the class. I am not able to lookup the key. I see that hash method is called during the find operation.

// key to be stored in unordered_map
class data {
    public:
    char c;
    int i;
    data(char cc,int ii) {
       c=cc;i=ii;
    }
};

class myhash {
    public:
    size_t operator()(const std::tr1::shared_ptr<data> d1 ) const { 
        std::cout << ">" <<  std::tr1::hash<int>()(d1->c) << std::endl; 
        return std::tr1::hash<int>()(d1->c); 
    }
};

int main() {
    std::tr1::unordered_map<std::tr1::shared_ptr<data>, char, myhash> umap;
    //build map
    std::tr1::shared_ptr<data> d1( new data('A',1));
    umap[d1]='C';
    std::tr1::shared_ptr<data> d2( new data('B',1));
    umap[d2]='C';
    std::tr1::shared_ptr<data> d3(new data('C',1));
    umap[d3]='F';
    std::tr1::shared_ptr<data> d4(new data('D',1));
    umap[d4]='E';
    std::tr1::shared_ptr<data> d5(new data('E',1));
    umap[d5]='F';
    std::tr1::shared_ptr<data> d6(new data('F',1));
    umap[d6]='F';

    std::cout << "--------------" << std::endl;

    for(std::tr1::unordered_map<std::tr1::shared_ptr<data>, char,myhash>::iterator itr = umap.begin(); itr!=umap.end(); itr++) {
        if(itr->first->c == itr->second) 
            continue;
        std::tr1::shared_ptr<data> d11( new data(itr->second,0));
        std::tr1::unordered_map<std::tr1::shared_ptr<data>, char,myhash>::iterator index = umap.find(d11);
        if(index != umap.end()) <<<<----- its always null here. Not sure why
            index->first->i += itr->first->i;
        else
            std::cout << "NULL" << std::endl;
    }

    for(std::tr1::unordered_map<std::tr1::shared_ptr<data>, char,myhash>::iterator itr = umap.begin(); itr!=umap.end(); itr++) 
        std::cout << itr->first->c << " " << itr->first->i << std::endl;
}

You need to implement an equality operator or functor for the key type of the map. Otherwise the equality operator for tr1::shared_ptr is used, and that doesn't do what you need.

For example,

struct myequal
{
  bool operator()(const std::tr1::shared_ptr<data>& lhs,
                  const std::tr1::shared_ptr<data>& rhs) const
  {
    return lhs->c == rhs->c;
  }
};

then

std::tr1::unordered_map<std::tr1::shared_ptr<data>, char, myhash, myequal> umap;

See a working example here .

It looks like you've defined a hash function but no equality function. So your 'identical' keys sort into the same hash buckets but don't index the same values in the map.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM