c++ - Using struct as KEY and VALUE for map. find() operation giving error -
code in c++:
#include <iostream> #include <map> #include <string> using namespace std; struct keyinfo { string key1; string key2; bool keyinfo::operator <(keyinfo &a) const { return ((this->key1<a.key1)&&(this->key2<a.key2)); } }; struct valueinfo { int value1; int value2; int value3; valueinfo(const int a,const int b,const int c) : value1(a),value2(b),value3(c) {} }; typedef std::map<keyinfo, valueinfo> maptype; int main() { maptype tmap; keyinfo k; k.key1="main"; k.key2="i"; valueinfo v(-2,-3322,9000); tmap.insert(maptype::value_type(k,v)); maptype::iterator it1=tmap.find(k); it1=tmap.find(k); if(it1!=tmap.end()) std::cout<<"success(k): "<<it1->second.value2<<std::endl; keyinfo e; e.key1="main"; e.key2="j"; //tmap.insert(std::pair<keyinfo,valueinfo>(e,v)); maptype::iterator it2=tmap.find(e); if (it2!=tmap.end()) std::cout<<"success(e): "<<(it2->second).value3<<std::endl; cin.get(); return 0; }
when compile code gave me error:
error c2679: binary '<' : no operator found takes right-hand operand of type 'const keyinfo1' (or there no acceptable conversion)
please let me know i'm going wrong? highly appreciated. thanks.
i have tried implement own operator , used in map<>, code looks follows:
#include <iostream> #include <map> #include <string> using namespace std; struct keyinfo { string key1; string key2; /*bool keyinfo::operator()(keyinfo const& left,keyinfo const& right) const{ return ((left.key1<right.key1)&&(left.key2<right.key2)); }*/ }; struct lesscomparer{ bool operator()(keyinfo const& left,keyinfo const& right) const{ return !(left.key1==right.key1 && left.key2==right.key2); } }; struct valueinfo { int value1; int value2; int value3; valueinfo(const int a,const int b,const int c) : value1(a),value2(b),value3(c) {} }; typedef std::map<keyinfo, valueinfo, lesscomparer> maptype; int main() { maptype tmap; keyinfo k; k.key1="main"; k.key2="i"; valueinfo v(-2,-3322,9000); tmap.insert(maptype::value_type(k,v)); maptype::iterator it1=tmap.find(k); it1=tmap.find(k); if(it1!=tmap.end()) std::cout<<"success(k): "<<it1->second.value2<<std::endl; keyinfo e; e.key1="main"; e.key2="j"; //tmap.insert(std::pair<keyinfo,valueinfo>(e,v)); maptype::iterator it2=tmap.find(e); if (it2!=tmap.end()) std::cout<<"success(e): "<<(it2->second).value3<<std::endl; cin.get(); return 0; }
here i'm using operator() return 0 iff both key1 , key2 of left , right equal. think same way map::less works, mean return false if equality condition satisfied.
it works fine in first case i.e. tmap.find(k) same key found. during call in second case i.e. tmap.find(e) pops error saying:
"debug assertion failed" expression: invalid operator <
your declaration of operator<
off.
struct keyinfo { string key1; string key2; bool keyinfo::operator <(keyinfo &a) const { return ((this->key1<a.key1)&&(this->key2<a.key2)); } };
... , several reasons:
- it error prefix declaration class name within class. should if define outside class. compilers laxist, standard says should not this.
- the reason cannot compile
operator<
should accept both operands either values (for simple things) orconst&
. here forgotconst
a
. - the definition incorrect,
operator<
has semantics off properties ofantisymmetry
not respected. - it recommended binary operators declared free functions outside class.
all in all, correct declaration , definition are:
struct keyinfo { std::string key1; std::string key2; }; inline bool operator<(keyinfo const& left, keyinfo const& right) { if (left.key1 < right.key1) { return true; } if (left.key1 > right.key1) { return false; } return left.key2 < right.key2; }
if can use boost, "simple" way implement is:
inline bool operator<(keyinfo const& left, keyinfo const& right) { return boost::tie(boost::cref(left.key1) , boost::cref(left.key2)) < boost::tie(boost::cref(right.key1), boost::cref(right.key2)); }
Comments
Post a Comment