jeudi 19 juillet 2018

std::map find fails when key is pointer

I am unable to get the std::map find to locate the correct row in the std::map. The key is a class pointer and I have created a struct (tdEcApplDataMapEq) to compare the class's binary arrays for a match.'

The problem is it doesn't work. I call FoEcApplData::operator== when the find starts. It says the first entry does not a match and then the find returns out pointing to the first item on the std::map list. There is no attempt by find to search the other map entries. Also the one match test failed (false), so why is find saying its a match?

This probably has something to do with the std::map declaration. std::map says the third argument is for std::less, but I am doing a == vs. <. If I change it to do < the same this happens. It enters FoEcApplData::operator< which return a true on the first check and find search stops with the search pointing to the 1st entry in the list.

How do I get find() to use the custom struct for the search?

My example adds 10 rows to FdTEcApplDataMap. It copies the CDH_DISABLE_XACT182 class into hold for the search later. I then do the find() test using hold as the search key.

Inside CDH_DISABLE_NCTCDNLD
Inside CDH_DISABLE_XACT181
Inside CDH_DISABLE_XACT182 <== this is the one I am searching for
Inside CDH_DISABLE_XACT183
Inside CDH_DISABLE_XACT184
Inside CDH_DISABLE_XACT185
Inside CDH_DISABLE_XACT186
Inside CDH_DISABLE_XACT187
Inside CDH_DISABLE_XACT188
Inside CDH_DISABLE_XACT189
Inside CDH_DISABLE_XACT190

This is the find:

    auto hazard = ExcludedCmdDict.find(&hold);
    if(hazard != ExcludedCmdDict.end())
    {
std::cout << "found it " << hazard->second << std::endl;
    }

This is the compare function being used:

bool FoEcApplData::operator==( const FoEcApplData& FoEcApplDataObject) const {

    if(myNumOfBytes <= FoEcApplDataObject.NumOfBytes()) 
    { 
        const EcTOctet* temp; 
        temp = FoEcApplDataObject.Data() ; 

        for(EcTInt i = 0; i < myNumOfBytes ; i++)
        { 
            if(myData[i] != temp[i])
            { 
                return false ; 
            } 
        } 
        return true;
    } 
    else        // myNumOfBytes > FoEcApplDataObject.NumOfBytes()
    {
        const EcTOctet* temp; 
        temp = FoEcApplDataObject.Data() ; 

        for(EcTInt i = 0; i < FoEcApplDataObject.NumOfBytes(); i++)
        {
            if(myData[i] != temp[i])
            { 
                return false ; 
            } 
        } 
        return true;
    }
}

This is the declaration for the std::map.

/*
Custom less for find on the FdTEcApplDataMap.
Needed since we are using poiners.

Returns - true - match, false - no match

node  - pointer to the item you are looking for
node2 - pointer to an item on the list
*/

struct tdEcApplDataMapEq {
    bool operator()(FoEcApplData *const& node, FoEcApplData *const& node2) const
    {
        return *node == *node2;
    }
};
typedef std::map< FoEcApplData *, std::string, tdEcApplDataMapEq> FdTEcApplDataMap;

Aucun commentaire:

Enregistrer un commentaire