我想将给定类的对象映射到另一个对象的对象。但是,我想要用作键的类不是由我编写的,而是一个带有一些值的简单struct
。 std :: map命令它的内容,我想知道它是如何做到的,如果任何一个任意类可以用作一个键,或者是否需要定义一组需求(运算符和不需要的话)。
如果是这样,我可以为实现运算符map使用的类创建一个包装器。我只需要知道我需要首先实现什么,并且没有一个类found online的引用指定它们。
答案 0 :(得分:61)
密钥所需要的只是它是可复制的和可分配的。
地图中的排序由第三个参数定义
template(以及构造函数的参数,如果使用的话)。这个
默认到std::less<KeyType>
,默认为<
运算符,
但是没有要求使用默认值。只是写一个比较
运算符(最好是作为功能对象):
struct CmpMyType
{
bool operator()( MyType const& lhs, MyType const& rhs ) const
{
// ...
}
};
请注意,它必须定义严格的排序,即如果CmpMyType()( a, b
)
返回true,则CmpMyType()( b, a )
必须返回false,如果
两者都返回false,元素被认为是相等的(成员)
相同的等价类)。
答案 1 :(得分:21)
您需要定义运算符&lt;,例如:
struct A
{
int a;
std::string b;
};
// Simple but wrong as it does not provide the strict weak ordering.
// As A(5,"a") and A(5,"b") would be considered equal using this function.
bool operator<(const A& l, const A& r )
{
return ( l.a < r.a ) && ( l.b < r.b );
}
// Better brute force.
bool operator<(const A& l, const A& r )
{
if ( l.a < r.a ) return true;
if ( l.a > r.a ) return false;
// Otherwise a are equal
if ( l.b < r.b ) return true;
if ( l.b > r.b ) return false;
// Otherwise both are equal
return false;
}
// This can often be seen written as
bool operator<(const A& l, const A& r )
{
// This is fine for a small number of members.
// But I prefer the brute force approach when you start to get lots of members.
return ( l.a < r.a ) ||
(( l.a == r.a) && ( l.b < r.b ));
}
答案 2 :(得分:3)
答案实际上在您链接的参考文献中,在“比较”模板参数的描述下。
唯一的要求是Compare
(默认为less<Key>
,默认使用operator<
来比较键)必须是“严格的弱排序”。
答案 3 :(得分:2)
与set
相同:该类必须具有“小于”精神的严格排序。要么重载适当的operator<
,要么提供自定义谓词。任何两个a
和b
对象!(a<b) && !(b>a)
将被视为相等。
地图容器实际上将按照该顺序提供的顺序保留所有元素,这就是如何通过键值实现O(log n)查找和插入时间。