[英]std::map<struct,struct>::find is not finding a match, but if i loop thru begin() to end() i see the match right there
struct chainout {
LONG cl;
std::string cs;
bool operator<(const chainout&o)const {
return cl < o.cl || cs < o.cs;
}
} ;
struct chainin{
std::string tm;
std::string tdi;
short mss;
LONG pinid;
bool operator<(const chainin&o)const {
return mss < o.mss || pinid < o.pinid || tm<o.tm; //no tdi right now it's always empty
}
};
std::map <chainin,chainout> chainmap;
std::map<chainin,chainout>::iterator it;
chainin ci;
chainout co;
string FADEDevicePinInfo::getNetAtPinIdTmTidMss (const LONG p,const string tm, const string tid,const LONG mss){
ci.tm=tm;
// ci.tdi=tid;
ci.tdi="";
ci.mss=(short)mss;
ci.pinid=p;
for (it=chainmap.begin();it!=chainmap.end();it++){
if(it->first.pinid==ci.pinid && it->first.tm==ci.tm&&it->first.mss==ci.mss && it->first.tdi==ci.tdi){
cout << "BDEBUG: found p["; cout<<it->first.pinid; cout<<"] tm["; cout<<it->first.tm.c_str();cout<<"] mss[";cout<<it->first.mss;cout<<"] : ";cout<<it->second.chainSignal.c_str();cout<<endl;
}
}
it=chainmap.find(ci);
if(it == chainmap.end()){
MSG(SEV_T,("no pin data found for pin[%ld]/tm[%s]/tdi[%s]/mss[%ld]",ci.pinid,ci.tm.c_str(),ci.tdi.c_str(),ci.mss));
}
return it->second.cs;
}
這既打印了成功找到的行,又由於 map::find 未返回匹配項而引發 sev_t 錯誤。 我做錯了什么?
我通過 < function 添加了打印語句,但它似乎正確地訂購了 map,當我進行查找時,它似乎找到了正確的 mss/pinid,但隨后只看到一個 tm,這是錯誤的 tm。
如評論中所述,您的比較運算符不好。 如果您不知道對象應該按什么順序排序,那么 std::map 或任何其他排序容器也不知道。
當您有多個要比較的東西時,請考慮決定哪個最重要,並使用 std::tie 來比較它們,如下所示:
#include <string>
#include <iostream>
struct chainout {
int cl;
std::string cs;
bool operator<(const chainout&o)const {
return std::tie(cl, cs) < std::tie(o.cl, o.cs);
}
};
int main(){
chainout a{ 1, "b" };
chainout b{ 2, "a" };
std::cout << (a < b) << std::endl;
std::cout << (b < a) << std::endl;
}
您的兩個struct
的operator<
都未正確實現。
std::map
需要鍵比較才能使用Strict Weak Ordering 。 這意味着當您的結構想要比較多個字段時,只有在較早的字段比較相等時,它們才需要比較后面的字段。 但是您沒有檢查這種情況。 如果一個實例中的任何字段比較小於另一個實例中的相應字段,則返回true
,而不管其他字段中的相等(或缺少)。 因此,您正在破壞 SWO,這會導致std::map
的查找中出現未定義的行為。
試試這個:
struct chainout {
LONG cl;
std::string cs;
bool operator<(const chainout &o) const {
/*
if (cl < o.cl) return true;
if (cl == o.cl) return (cs < o.cs);
return false;
*/
return (cl < o.cl) || ((cl == o.cl) && (cs < o.cs));
}
};
struct chainin{
std::string tm;
std::string tdi;
short mss;
LONG pinid;
bool operator<(const chainin &o) const {
if (mss < o.mss) return true;
if (mss == o.mss) {
if (pinid < o.pinid) return true;
if (pinid == o.pinid) return (tm < o.tm);
}
return false;
}
};
實現這一點的更簡單方法是使用std::tie()
代替,它有自己的operator<
為您處理此問題,例如:
struct chainout {
LONG cl;
std::string cs;
bool operator<(const chainout &o) const {
return std::tie(cl, cs) < std::tie(o.cl, o.cs);
}
};
struct chainin{
std::string tm;
std::string tdi;
short mss;
LONG pinid;
bool operator<(const chainin &o) const {
return std::tie(mss, pinid, tm) < std::tie(o.mss, o.pinid, o.tm);
}
};
無論哪種方式,然后std::map::find()
應該按預期工作,例如:
std::map<chainin, chainout> chainmap;
string FADEDevicePinInfo::getNetAtPinIdTmTidMss (const LONG p, const string tm, const string tid, const LONG mss)
{
chainin ci;
ci.tm = tm;
//ci.tdi = tid;
ci.tdi = "";
ci.mss = (short) mss;
ci.pinid = p;
std::map<chainin, chainout>::iterator it = chainmap.find(ci);
if (it != chainmap.end()) {
cout << "BDEBUG: found"
<< " p[" << it->first.pinid << "]"
<< " tm[" << it->first.tm << "]"
<< " mss[" << it->first.mss << "]"
<< " : " << it->second.cs
<< endl;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.