Can I use an stl map if I plan to use arbitrary cl

2019-06-21 04:55发布

问题:

I'm new to STL. The thing stumping me about using a map to store arbitrary objects:

std::map<MyClassObj, MyDataObject> MyMap;

is how I find objects. How would MyMap.find (MyClassObjInstance) work for instance? Do I need to implement my own iterator and provide some standard functions which would include some equivalence function? Any examples would be appreciated.

Is there another method to store an associated list of arbitrary objects using standard libraries? I'm already using stl to maintain platform portability, and would prefer not to add another library dependency like BOOST.

回答1:

std::map has a third template argument, after key and value, to denote what function is going to be used to compare keys. By default, it is std::less, which in it's turn uses operator<. So if your class has an operator<, it's ok, else you can provide a comparator of your own.



回答2:

All of you need is to define operator< for MyClassObj. For more information about std::map you could read here.

According to C++ Standard 23.1.2:

The phrase ‘‘equivalence of keys’’ means the equivalence relation imposed by the comparison and not the operator== on keys. That is, two keys k1 and k2 are considered to be equivalent if for the comparison object comp, comp(k1, k2) == false && comp(k2, k1) == false.

By default comp is std::less.

According to C++ Standard 20.3.3:

template <class T> struct less : binary_function<T,T,bool> {
bool operator()(const T& x, const T& y) const;
};

// operator() returns x < y.

Surely, you could define stand alone functor comp for comparison.



回答3:

The full type for map is

template < class Key, class T, class Compare = less<Key>,
       class Allocator = allocator<pair<const Key,T> > > class map;

It uses less than by default but as long as you pass in a class that has operator () overloaded to take two instances of the object and returns a bool all is well. note if you give it comp(a,b) and it returns true, then a should come before b in the ordering.



回答4:

Yes, you can use your own type/object as a key. They'll have to implement the less-than operator (operator<) as all ordered standard C++ containers do use this operator to test for ordering and equality.