我想将给定类的对象映射到另一个类的对象。但是,我想用作键的类不是我编写的,它很简单struct
,只有几个值。std :: map对其内容进行排序,我想知道它是如何执行的,是否可以将任何任意类用作键,或者是否需要定义一组需求(操作符和其他内容)。
如果是这样,我可以为实现操作符映射使用的类创建一个包装器。我只需要知道我首先需要实现的内容,而在网上找到的类的引用都没有指定它们。
Answers:
密钥所需要的只是可复制和可分配。映射中的顺序由模板的第三个参数(以及构造函数的参数(如果使用))定义。该
默认到std::less<KeyType>
,其默认为<
运营商,但没有规定使用默认值。只需编写一个比较运算符(最好是一个功能对象):
struct CmpMyType
{
bool operator()( MyType const& lhs, MyType const& rhs ) const
{
// ...
}
};
请注意,它必须定义严格的顺序,即如果CmpMyType()( a, b
)
返回true,则CmpMyType()( b, a )
必须返回false,并且如果两个都返回false,则将元素视为相等(同一等效类的成员)。
operator<
为每个班级提供一个。他以椅子为例。您可以按身高,腿数或什至颜色对它们进行排序,但是您选择的选项完全是任意的,实际上椅子没有自然的排序,而是容器必须选择椅子的方式订购。往往一个operator<
似乎是显而易见的选择真的是刚一出来的许多可能性,因此不属于入级....沿着这条线的东西是他的推理。
operator <
并std::less
没有为你做它,然后写一个比较函数作为一个额外的参数给的std ::地图模板声明。如果执行比较器函数,则最好将其声明为函子对象>>这样做函子对象的原因是,在编译时将对象实例优化,而函数指针实际上存在于map对象中而且要优化起来要困难得多。
您需要定义operator <,例如这样:
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 ));
}