C++ 如何使用用户定义类型作为键的std::maps?

C++ 如何使用用户定义类型作为键的std::maps?,c++,dictionary,stl,containers,stdmap,C++,Dictionary,Stl,Containers,Stdmap,我想知道为什么不能将STL映射与用户定义的类一起使用。当我编译下面的代码时,我得到了以下神秘的错误消息。这是什么意思?另外,为什么它只发生在用户定义的类型上?(基本类型用作键时可以使用。) C:\MinGW\bin..\lib\gcc\mingw32\3.4.5……。\n在 成员函数'bool std::less::operator(), const _-Tp&)const[with _-Tp= 类别1]':| C:\MinGW\bin..\lib\gcc\mingw32\3.4.5……。\in

我想知道为什么不能将STL映射与用户定义的类一起使用。当我编译下面的代码时,我得到了以下神秘的错误消息。这是什么意思?另外,为什么它只发生在用户定义的类型上?(基本类型用作键时可以使用。)

C:\MinGW\bin..\lib\gcc\mingw32\3.4.5……。\n在 成员函数'bool std::less::operator(), const _-Tp&)const[with _-Tp= 类别1]':|

C:\MinGW\bin..\lib\gcc\mingw32\3.4.5……。\include\C++\3.4.5\bits\stl_map.h | 338 |实例化 来自“\u Tp&std::map::operator[](const\u Key&)[其中,\u Key=Class1,\u Tp=int,\u Compare=std::less,\u Alloc=std::allocator>]”|

C:\Users\Admin\Documents\dev\sandbox\sandbox\sandbox.cpp | 24 |实例化 从这里|


C:\MinGW\bin..\lib\gcc\mingw32\3.4.5……。\include\C++\3.4.5\bits\stl_function.h | 227 |错误:与“operator不匹配您需要定义
operator您需要在默认情况下定义
operator(和)用于确定排序。因此,您需要在默认情况下定义
运算符(并使用)以确定排序。因此,您需要定义
操作符键必须是可比较的,但是您没有定义合适的
操作符键必须是可比较的,但是您没有定义合适的
操作符您不必定义
操作符您不必定义
操作符
类键
{
int m_值;
公众:
布尔运算符的值类密钥
{
int m_值;
公众:
布尔运算符的值cout正确的解决方案是为类/结构专门化
std::less

•基本上,cpp中的地图是作为二进制搜索树实现的

  • BST比较节点的元素以确定树的组织
  • 元素比较小于父节点的节点放置在父节点的左侧,元素比较大于父节点元素的节点放置在右侧。 i、 e
  • 对于每个节点,node.left.key BST中的每个节点都包含元素,在映射的情况下,其键和值以及键都应该是有序的。 有关映射实现的详细信息:

    对于cpp映射,键是节点的元素,值不参与树的组织,只是补充数据


    因此,这意味着键应该与
    std::less
    操作符兼容正确的解决方案是为类/结构专门化
    std::less

    •基本上,cpp中的地图是作为二进制搜索树实现的

  • BST比较节点的元素以确定树的组织
  • 元素比较小于父节点的节点放置在父节点的左侧,元素比较大于父节点元素的节点放置在右侧。 i、 e
  • 对于每个节点,node.left.key BST中的每个节点都包含元素,在映射的情况下,其键和值以及键都应该是有序的。 有关映射实现的详细信息:

    对于cpp映射,键是节点的元素,值不参与树的组织,只是补充数据


    因此,这意味着键应该与
    std::less
    操作符兼容。我想对Pavel Minaev的进行一点扩展,在阅读我的答案之前,您应该先阅读它。如果要比较的成员(例如问题代码中的
    id
    ),Pavel提供的两种解决方案都不会编译是私有的。在这种情况下,VS2013为我抛出以下错误:

    错误C2248:“Class1::id”:无法访问类“Class1”中声明的私有成员

    正如天行者在on Pavel的回答中提到的,使用
    友人
    声明会有所帮助。如果您想知道正确的语法,请参阅:

    class Class1
    {
    public:
        Class1(int id) : id(id) {}
    
    private:
        int id;
        friend struct Class1Compare;      // Use this for Pavel's first solution.
        friend struct std::less<Class1>;  // Use this for Pavel's second solution.
    };
    
    然后,您可以使用它代替
    友元
    声明(即,您比较
    lhs.getId()
    )。 因为,您还可以使用for Pavel的第一个解决方案,而不是定义comparator函数对象类。 将所有内容放在一起,代码可以编写如下:

    class Class1
    {
    public:
        Class1(int id) : id(id) {}
        int getId() const { return id; }
    
    private:
        int id;
    };
    
    auto comp = [](const Class1& lhs, const Class1& rhs){ return lhs.getId() < rhs.getId(); };
    std::map<Class1, int, decltype(comp)> c2int(comp);
    
    auto comp=[](常量Class1&lhs,常量Class1&rhs){返回lhs.getId()

    我想对Pavel Minaev的进行一点扩展,在阅读我的答案之前,您应该先阅读Pavel Minaev的答案。如果要比较的成员(例如问题代码中的
    id
    )是私有成员,则Pavel提供的两种解决方案都不会编译。在这种情况下,VS2013为我抛出以下错误:

    错误C2248:“Class1::id”:无法访问类“Class1”中声明的私有成员

    正如天行者在on Pavel的回答中提到的,使用
    友人
    声明会有所帮助。如果您想知道正确的语法,请参阅:

    class Class1
    {
    public:
        Class1(int id) : id(id) {}
    
    private:
        int id;
        friend struct Class1Compare;      // Use this for Pavel's first solution.
        friend struct std::less<Class1>;  // Use this for Pavel's second solution.
    };
    
    然后,您可以使用它代替
    友元
    声明(即,您比较
    lhs.getId()
    )。 因为,您还可以使用for Pavel的第一个解决方案,而不是定义comparator函数对象类。 将所有内容放在一起,代码可以编写如下:

    class Class1
    {
    public:
        Class1(int id) : id(id) {}
        int getId() const { return id; }
    
    private:
        int id;
    };
    
    auto comp = [](const Class1& lhs, const Class1& rhs){ return lhs.getId() < rhs.getId(); };
    std::map<Class1, int, decltype(comp)> c2int(comp);
    
    auto comp=[](常量Class1&lhs,常量Class1&rhs){返回lhs.getId()

    作为fac的一部分
    class Class1
    {
    public:
        Class1(int id) : id(id) {}
    
    private:
        int id;
        friend struct Class1Compare;      // Use this for Pavel's first solution.
        friend struct std::less<Class1>;  // Use this for Pavel's second solution.
    };
    
    class Class1
    {
    public:
        Class1(int id) : id(id) {}
        int getId() const { return id; }
    
    private:
        int id;
    };
    
    auto comp = [](const Class1& lhs, const Class1& rhs){ return lhs.getId() < rhs.getId(); };
    std::map<Class1, int, decltype(comp)> c2int(comp);