如何在STL中设置自定义的默认比较函数

How to set self-defined default compare function in STL

本文关键字:默认 比较 函数 自定义 设置 STL      更新时间:2023-10-16

假设现在我有一个二维坐标数组,我想根据两个条件选择两个坐标:

  • 选择最左和最右坐标
  • 选择顶部和底部坐标

为了完成这个任务,我定义了以下函数:

template <typename T>
class  Coordinate //:public common::BasicCoordinate<T>
{
public:
    T x_;  ///< x_coordinate
    T y_;  ///< y_coordinate
};

template<typename T>
struct compare_x_coordinate 
{
    bool operator() (const Coordinate<T> &i,const Coordinate<T> &j) 
    { return i.x_<j.x_; }
} ;
template<typename T>
struct compare_y_coordinate 
{
    bool operator() (const Coordinate<T> &i,const Coordinate<T> &j) 
    { return i.y_<j.y_; }
} ;

然后我要做的是写一个函数,它从基于compare_x_coordinatecompare_y_coordinate的坐标范围中选择两个坐标。我可以用两个函数来做到这一点:

template<typename T >
    void find_left_right_points(const std::vector<Coordinate<T> > &ptArray, 
        Coordinate<T> &left, 
        Coordinate<T> &right )
    {
       compare_x_coordinate<T> mycompare; 
        std::vector<Coordinate<T> >::const_iterator it_max = std::max_element(ptArray.begin(), ptArray.end(), mycompare);
        int index_max = it_max-ptArray.begin();

        std::vector<Coordinate<T> >::const_iterator it_min = std::min_element(ptArray.begin(),ptArray.end(),mycompare); 
        int index_min = it_min-ptArray.begin();
        left    = ptArray[index_min];
        right   = ptArray[index_max];
    } ;

template<typename T >
void find_top_bottom_points(const std::vector<Coordinate<T> > &ptArray, 
    Coordinate<T> &left, 
    Coordinate<T> &right )
{
   compare_y_coordinate<T> mycompare; 
    std::vector<Coordinate<T> >::const_iterator it_max = std::max_element(ptArray.begin(), ptArray.end(), mycompare);
    int index_max = it_max-ptArray.begin();

std::vector<Coordinate<T> >::const_iterator it_min = std::min_element(ptArray.begin(),ptArray.end(),mycompare); 
int index_min = it_min-ptArray.begin();
left    = ptArray[index_min];
right   = ptArray[index_max];
} ;

当然,最好的方法是将这两个函数合二为一:

template<typename T >
    void find_points(const std::vector<Coordinate<T> > &ptArray, 
        Coordinate<T> &left, 
        Coordinate<T> &right, 
        // I do not know how to write the default comparasion function 
        )
    {
     //  compare_x_coordinate<T> mycompare; 
        std::vector<Coordinate<T> >::const_iterator it_max = std::max_element(ptArray.begin(), ptArray.end(), mycompare);
        int index_max = it_max-ptArray.begin();

        std::vector<Coordinate<T> >::const_iterator it_min = std::min_element(ptArray.begin(),ptArray.end(),mycompare); 
        int index_min = it_min-ptArray.begin();
        left    = ptArray[index_min];
        right   = ptArray[index_max];
    } ;

但是,我不知道如何在上面的例子中编写默认的比较函数,有什么想法吗?谢谢。

编辑:该函数的一个可能的应用应该是:

void main(void)
{
  std::vector<Coordinate> ptArray;
  // step 1: fill the coordinates 
  ptArray.push_back(...)
  // step 2: select the most left and right coordinates
  Coordinate left, right;
  find_points(ptArray,left,right);
  // step 3: select the top and bottom coordinates
  Coordinate top,bottom;
  find_points(ptArray, top,left, find_top_bottom_points);
}

如果我理解正确的话,一种方法是:

template<typename T, class Compare >
void find_points(const std::vector<Coordinate<T> > &ptArray, 
                 Coordinate<T> &left, 
                 Coordinate<T> &right,
                 const Compare &cmp) {
    find_points(ptArray, left, right, cmp);
}
template<typename T >
void find_points(const std::vector<Coordinate<T> > &ptArray, 
                 Coordinate<T> &left, 
                 Coordinate<T> &right) {
    find_points(ptArray, left, right, default_compare);
}

您也可以使用boost::function(但可能会损失性能):

template<typename T >
void find_points(const std::vector<Coordinate<T> > &ptArray, 
                 Coordinate<T> &left, 
                 Coordinate<T> &right,
                 const boost::function<bool(const Coordinate<T>&, Coordinate<T>&)> &cmp =
                     compare_x_coordinate<T>())
{
    ...
}