pet*_*mlm 5 c++ containers map
所以假设我有一个像这样的课程:
class Point
{
private:
int x, y;
public:
void setX(int arg_x) { x = arg_x; }
void sety(int arg_y) { y = arg_y; }
int getX() const { return x; }
int gety() const { return y; }
};
Run Code Online (Sandbox Code Playgroud)
现在我想要一张这样的地图:
map<Point, Point> m;
Run Code Online (Sandbox Code Playgroud)
但我需要第三个参数.我在cplusplus中读到第三个参数是比较一些东西,但我不明白那是什么东西.任何人都能解释一下吗?
par*_*mar 22
如果不需要单独的比较函数,可以使用这种方法扩展类
class Point
{
private:
int x, y;
public:
bool operator<( const Point& other) const
{
if ( x == other.x )
{
return y < other.y;
}
return x < other.x;
}
};
Run Code Online (Sandbox Code Playgroud)
默认情况下,stl映射通过一些排序概念对其中的所有元素进行排序.在这种情况下,使用此运算符.有时您无法控制Point类,或者您可能希望在两个不同的映射中使用它,每个映射都定义自己的顺序.例如,一个地图可能先按x对点进行排序,而另一个可能先按y排序.因此,如果比较运算符独立于Point类,则可能会有所帮助.你可以做这样的事情.
class Point
{
public:
int x, y;
};
struct PointComparer
{
bool operator()( const Point& first , const Point& second) const
{
if ( first.x == second.x )
{
return first.y < second.y;
}
return first.x < second.x;
}
};
map<Point, Point , PointComparer> m;
Run Code Online (Sandbox Code Playgroud)
您需要的是定义Point项的排序.
这可以通过不同方式完成:
operator <for Point您可以提供<操作员的重载,其原型是:
bool operator < (const Point & p_lhs, const Point & p_rhs) ;
Run Code Online (Sandbox Code Playgroud)
例如,对于我的测试,我使用了以下一个:
bool operator < (const Point & p_lhs, const Point & p_rhs)
{
if(p_lhs.getX() < p_rhs.getX()) { return true ; }
if(p_lhs.getX() > p_rhs.getX()) { return false ; }
return (p_lhs.getY() < p_rhs.getY()) ;
}
Run Code Online (Sandbox Code Playgroud)
这是最简单的方法,但它在语义上假设上面定义的顺序是正确的默认顺序.
如果您不愿意提供<操作员,或者想要拥有多个地图,每个地图都有自己的排序,那么您的解决方案就是为地图提供一个仿函数.这是为地图定义的第三个模板参数:
template < class Key, class T, class Compare = less<Key>,
class Allocator = allocator<pair<const Key,T> > > class map;
Run Code Online (Sandbox Code Playgroud)
仿函数必须具有以下签名:
struct MyCompareFunctor
{
bool operator() (const Point & p_lhs, const Point & p_rhs)
{
// the code for comparison
}
} ;
Run Code Online (Sandbox Code Playgroud)
所以,对于我的测试,我只写了以下内容:
struct MyCompare
{
bool operator() (const Point & p_lhs, const Point & p_rhs)
{
if(p_lhs.getX() > p_rhs.getX()) { return true ; }
if(p_lhs.getX() < p_rhs.getX()) { return false ; }
return (p_lhs.getY() > p_rhs.getY()) ;
}
} ;
Run Code Online (Sandbox Code Playgroud)
并在我的地图中使用它:
std::map<Point, Point, MyCompare> map ;
Run Code Online (Sandbox Code Playgroud)
Etvoilà......
std::less的Point我认为这样做没有意义,但总是很高兴知道:你可以专门std::less为你的Point班级设计模板结构
#include <functional>
namespace std
{
template<>
struct less<Point> : binary_function <Point,Point,bool>
{
bool operator() (const Point & p_lhs, const Point & p_rhs)
{
if(p_lhs.getX() < p_rhs.getX()) { return true ; }
if(p_lhs.getX() > p_rhs.getX()) { return false ; }
return (p_lhs.getY() < p_rhs.getY()) ;
}
} ;
}
Run Code Online (Sandbox Code Playgroud)
就operator <地图而言,这至少与重载相同.
至于operator <上面的解决方案,从语义上讲,这个解决方案假定上面定义的顺序是正确的默认顺序std:less.
请注意,默认std::less实现调用operator <的是模板化类型.让一个给出不同于另一个的结果可以被认为是语义错误.