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

Avi*_*ash 0 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;
    }
Run Code Online (Sandbox Code Playgroud)

我很困惑我的std::map工作方式,因为我感兴趣的元素std::map是指针ElementType.我真正想要的是存储实际数据std::set并使用指向这些元素的指针std::map

主要的混乱是围绕着 less than operator

Ste*_*sop 7

您的地图,正常情况下std::map<ElementType*, std::list<ElementType*> >使用std::less键类型作为其比较器.

std::less对于指针类型,定义为生成一致的排序,但排序仅基于地址,而不是基于它可能指向的任何内容.

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

您可以编写一个带两个指针的比较器,并比较它们指向的对象.这当然假设一旦你使用指针作为地图中的一个关键字,你就确保它所指向的对象(set我假设,但如果不是,那么shared_ptr在这里插入样板讲座).由于Element<int>复制起来很便宜,因此使用它ElementType作为密钥几乎肯定会更好ElementType*.但是,如果int仅仅是为了将来使用的东西,那么复制起来很昂贵,那么就改变map比较器.

你可能不关心中的元素顺序map.如果你不这样做,并且你所查看的唯一内容map是指向对象的指针set,那么ElementType*在没有指定比较器的情况下使用map键应该没问题.