开发者

STL set and map for the same user defined type

开发者 https://www.devze.com 2023-04-07 16:37 出处:网络
I have a class for which I have defined comparison operator. Following is the code I wrote #include <set>

I have a class for which I have defined comparison operator. Following is the code I wrote

#include <set>
#include <map>
#include <list>

    template <typename _TyV>
    class Element {
    public:
        Element(_TyV in) :  m_Label(in){}
        ~Element() {}
        bool operator < ( const Element & right) const {
            return m_Label < right.m_Label;
        }
    private:
        _TyV m_Label;
    protected:
    };
    typedef Element<int> ElementType;

    int main ( int argc, char **argv) { 
        std::set<ElementType> mySet;
        for ( int i = 0; i < 10; i++) {
            mySet.insert(ElementType(i));
        }
        std::map<ElementType*, std::lis开发者_JAVA技巧t<ElementType*> > myMapList;
        return 0;
    }

I am confuse on how my std::map will work since the element I am interested in the std::map is pointer to the ElementType. What I actually want is to store actual data in std::set and use pointers to these element in the std::map

Major confusion is around the less than operator


Your map, std::map<ElementType*, std::list<ElementType*> > uses std::less on the key type as its comparator, as normal.

std::less for pointer types is defined to produce a consistent ordering, but the ordering is based on the address only, not on anything that it might point to.

So, your set sorts its contents according to the operator< in Element, but the map sorts them according to the actual pointer value of the key. That probably isn't what you want: (1) it makes different Element<int> objects containing the same m_Label value act as different keys in the map, and (2) it means the map will be in a different order from the set. But std::map can take an extra template argument to provide a comparator, so you can change that.

You could write a comparator that takes two pointers, and compares the objects they point to. This assumes of course that once you've used a pointer as a key in the map, you ensure that the object it points to sticks around (in the set, I assume, but if not then insert boilerplate lecture about shared_ptr here). Since Element<int> is cheap to copy, it would almost certainly be better to use ElementType as the key instead of ElementType*. But if int is just standing in for something you'll use in future that's expensive to copy, then change the map comparator.

You might not care about the order of elements in the map. If you don't, and if the only things you ever look up in the map are pointers to objects in the set, then using ElementType* as the map key without specifying a comparator should be fine.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号