STL为相同的用户定义类型设置和映射

时间:2011-09-27 09:57:31

标签: c++ stl

我有一个我定义了比较运算符的类。以下是我写的代码

#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::list<ElementType*> > myMapList;
        return 0;
    }

我对std::map的工作方式感到困惑,因为我对std::map感兴趣的元素是指向ElementType的指针。我真正想要的是将实际数据存储在std::set中,并在std::map

中使用指向这些元素的指针

less than operator

周围存在严重混淆

1 个答案:

答案 0 :(得分:7)

您的地图std::map<ElementType*, std::list<ElementType*> >正常使用密钥类型std::less作为其比较器。

指针类型的

std::less被定义为产生一致的排序,但排序仅基于地址,而不是基于它可能指向的任何内容。

因此,您的集合根据operator<中的Element对其内容进行排序,但地图会根据键的实际指针值对它们进行排序。这可能不是你想要的:(1)它使包含相同Element<int>值的不同m_Label对象充当地图中的不同键,(2)它表示地图将在来自集合的不同顺序。但std::map可以使用额外的模板参数来提供比较器,因此您可以更改它。

您可以编写一个带两个指针的比较器,并比较它们指向的对象。这当然假设一旦你使用指针作为地图中的一个关键点,你就确保它所指向的对象(我假设在set中),但如果没有,那么插入关于{的样板讲座{1}}这里)。由于shared_ptr复制起来很便宜,因此使用Element<int>代替ElementType几乎肯定会更好。但是,如果ElementType*仅代表您将来要使用的复制费用很高,那么请更改int比较器。

您可能不关心map中元素的顺序。如果你不这样做,并且你在map中查找的唯一内容是指向map中对象的指针,那么使用set作为映射键而不指定比较器应该没事。