2016-06-16 132 views
1

在下面的代码中,我试图了解map查找如何与用户定义的数据一起作为关键字。使用std :: map时出错

#include <iostream> 
#include <map> 
#include <boost/tuple/tuple.hpp> 
#include <boost/tuple/tuple_io.hpp> 

#include "unicode/coll.h" 

using namespace std; 
using namespace icu; 

class mystring { 
public: 
    std::string s; 
    bool operator==(const mystring &s1) const; 
    bool operator!=(const mystring &s) const; 
    bool operator<(const mystring &s1) const; 
    bool operator>(const mystring &s1) const; 
    bool operator<=(const mystring &s1) const; 
    bool operator>=(const mystring &s1) const; 
}; 

int caseCompare(UnicodeString& str1, int32_t len1, UnicodeString& str2, int32_t len2) 
{ 
    int ret; 
    ret = str1.caseCompare(0, len1, str2, 0, len2, 0); 
    cout << "caseCompare: " << ret << endl; 
    return ret; 
} 

bool mystring::operator==(const mystring &s1) const 
{ 
    cout << "== operator" << "\n"; 
    cout << s << "\t" << s1.s << "\n"; 
    UnicodeString us1(s.c_str(), s.length()); 
    UnicodeString us2(s1.s.c_str(), s1.s.length()); 

    if(caseCompare(us1, s.length(), us2, s1.s.length() != 0)) { 
     return 0; 
    } 
    return 1; 
} 

bool mystring::operator<(const mystring &s1) const 
{ 
    UnicodeString us1(s.c_str(), s.length()); 
    UnicodeString us2(s1.s.c_str(), s1.s.length()); 

    int ret; 

    cout << "< operator" << "\n"; 
    cout << s << "\t" << s1.s << "\n"; 

    size_t smaller_size; 
    if (s.size() < s1.s.size()) { 
     smaller_size = s.size(); 
    } else { 
     smaller_size = s1.s.size(); 
    } 

    ret = caseCompare(us1, s.length(), us2, s1.s.length() != 0); 
    if(ret != 0) { 
     if (ret < 0) { 
      return 1; 
     } else { 
      return 0; 
     } 
    } 
    if ((s.size() == s1.s.size()) || (s.size() > s1.s.size())) { 
     return 0; 
    } else { 
     return 1; 
    } 
} 

bool mystring::operator!=(const mystring &s1) const 
{ 
    cout << "!= operator" << "\n"; 
    cout << s << "\t" << s1.s << "\n"; 

    if (!(*this == s1)) { 
     return 1; 
    } else { 
     return 0; 
    } 
} 

bool mystring::operator>(const mystring &s1) const 
{ 
    cout << "> operator" << "\n"; 
    cout << s << "\t" << s1.s << "\n"; 

    if ((!(*this < s1)) && (!(*this == s1))) { 
     return 1; 
    } else { 
     return 0; 
    } 
} 

bool mystring::operator<=(const mystring &s1) const 
{ 
    cout << "<= operator" << "\n"; 
    cout << s << "\t" << s1.s << "\n"; 

    if ((*this < s1) || (*this == s1)) { 
     return 1; 
    } else { 
     return 0; 
    } 
} 

bool mystring::operator>=(const mystring &s1) const 
{ 
    cout << ">= operator" << "\n"; 
    cout << s << "\t" << s1.s << "\n"; 

    if ((*this > s1) || (*this == s1)) { 
     return 1; 
    } else { 
     return 0; 
    } 
} 

typedef boost::tuple<class mystring, class mystring> Key; 
int data = 100; 

typedef std::map<Key, int, std::less<Key> > Testmap; 
Testmap map1; 

int main(void) 
{ 
    mystring str1; 
    mystring str2; 

    string str3, str4; 

    cout << "String1: " << endl; 
    cin >> str3; 
    cout << "String2: " << endl; 
    cin >> str4; 

    str1.s = str3; 
    str2.s = str4; 

    Key fk = boost::make_tuple(str1, str2); 
    map1.insert(std::make_pair(fk, data)); 

    cout << "String1: " << endl; 
    cin >> str3; 
    cout << "String2: " << endl; 
    cin >> str4; 

    str1.s = str3; 
    str2.s = str4; 

    fk = boost::make_tuple(str1, str2); 

    Testmap::iterator itr = map1.find(fk); 
    if (itr != map1.end()) { 
     cout << itr->second << "\n"; 
    } else { 
     cout << "Not found"; 
    } 

    return 0; 
} 

当该代码被编译,我得到这个错误:

$ g++ map_test.cc -licuuc -licui18n 
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../include/c++/4.4.5/string:50, 
       from /usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../include/c++/4.4.5/bits/locale_classes.h:42, 
       from /usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../include/c++/4.4.5/bits/ios_base.h:43, 
       from /usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../include/c++/4.4.5/ios:43, 
       from /usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../include/c++/4.4.5/ostream:40, 
       from /usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../include/c++/4.4.5/iostream:40, 
       from map_test.cc:1: 
/usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../include/c++/4.4.5/bits/stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = boost::tuples::tuple<mystring, mystring, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>]’: 
/usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../include/c++/4.4.5/bits/stl_tree.h:1170: instantiated from ‘std::pair<typename std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(const _Val&) [with _Key = boost::tuples::tuple<mystring, mystring, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>, _Val = std::pair<const boost::tuples::tuple<mystring, mystring, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>, int>, _KeyOfValue = std::_Select1st<std::pair<const boost::tuples::tuple<mystring, mystring, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>, int> >, _Compare = std::less<boost::tuples::tuple<mystring, mystring, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> >, _Alloc = std::allocator<std::pair<const boost::tuples::tuple<mystring, mystring, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>, int> >]’ 
/usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../include/c++/4.4.5/bits/stl_map.h:500: instantiated from ‘std::pair<typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(const std::pair<const _Key, _Tp>&) [with _Key = boost::tuples::tuple<mystring, mystring, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>, _Tp = int, _Compare = std::less<boost::tuples::tuple<mystring, mystring, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> >, _Alloc = std::allocator<std::pair<const boost::tuples::tuple<mystring, mystring, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>, int> >]’ 
map_test.cc:146: instantiated from here 
/usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../include/c++/4.4.5/bits/stl_function.h:230: error: no match for ‘operator<’ in ‘__x < __y’ 

我想这是无法找到<运营商,但是这是在class mystring定义。还是它抱怨缺乏分配器方法?

谢谢!

回答

1

就包括boost/tuple/tuple_comparison.hpp

作出比较运营商按照您的要求,我已经展示它作为一个例子。

+1

http://www.boost.org/libs/tuple/doc/tuple_users_guide.html#using_library – llonesmiz

+2

@jv_ oops..updated答案,谢谢! – Arunmu

+0

您的比较运算符看起来不太正确。 – juanchopanza