C++ 如何使用用户定义类型作为键的std::maps?
我想知道为什么不能将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++ 如何使用用户定义类型作为键的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
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);