C++ 使用类成员函数作为函数指针?

C++ 使用类成员函数作为函数指针?,c++,C++,我试图将一个指向类的成员函数的函数指针传递给std::unique(),并得到一些我无法破译的编译器错误 // So this will otherwise compile class Vec2 {}; class Polygon {}; // ConvexHull.h: #include <vector> #include <algorithm> class ConvexHull { public: // Used to sort an array of vec

我试图将一个指向类的成员函数的函数指针传递给std::unique(),并得到一些我无法破译的编译器错误

// So this will otherwise compile
class Vec2 {};
class Polygon {};

// ConvexHull.h:
#include <vector>
#include <algorithm>
class ConvexHull {
public:
   // Used to sort an array of vectors so the bottom-right element is first:
   bool bottomRight(const Vec2& a, const Vec2& b);
   // Used to determine if coordinates are equivalent:
   bool vecEqual(const Vec2& a, const Vec2& b);
   Polygon chGrahamScan(std::vector<Vec2> points);
};

// ConvexHull.cpp:
bool ConvexHull::bottomRight(const Vec2& a, const Vec2& b) {
  // implementation...
  return false; // So this will otherwise compile
}

bool ConvexHull::vecEqual(const Vec2& a, const Vec2& b) {
  // implementation...
  return false; // So this will otherwise compile
}

Polygon ConvexHull::chGrahamScan(std::vector<Vec2> points) {
  // Sort according to bottom right:
  std::sort(points.begin(),points.end(),bottomRight); // !!!Does not compile!!!
  std::vector<Vec2>::iterator it;
  // Get rid of duplicate points:
  it = std::unique(points.begin(),points.end(),vecEqual); // !!!Does not compile!!!
  // rest of implementation...
  Polygon poly; // So this will otherwise compile
  return poly;
}

int main(){return 0;} // again, to allow this to otherwise compile
//否则将编译
类Vec2{};
类多边形{};
//ConvexHull.h:
#包括
#包括
凸形类{
公众:
//用于对向量数组进行排序,使右下角元素位于第一位:
布尔右下角(常数向量2&a、常数向量2&b);
//用于确定坐标是否相等:
布尔向量相等(常量向量2&a、常量向量2&b);
多边形chGrahamScan(标准::矢量点);
};
//ConvexHull.cpp:
布尔凸布尔::右下角(常数向量2&a,常数向量2&b){
//实施。。。
返回false;//否则将编译
}
布尔凸布尔::向量相等(常量向量2&a,常量向量2&b){
//实施。。。
返回false;//否则将编译
}
多边形凸圆::chGrahamScan(标准::向量点){
//按右下角排序:
排序(points.begin(),points.end(),bottomRight);/!!!不编译!!!
std::vector::it迭代器;
//消除重复点:
it=std::unique(points.begin(),points.end(),vecEqual);/!!!不编译!!!
//其余的实现。。。
Polygon poly;//否则将编译
返回多边形;
}
int main(){return 0;}//再次,以允许以其他方式编译
忽略这两条虚线,这就足够编译一些东西了。请帮忙!我不确定我在这里做错了什么。我知道这个测试代码说members函数是公共的,但我的最终目标是让它们成为私有函数,对用户隐藏,但仍然在convxhull::chGrahamScan()中按排序和唯一性内部使用。这不是我打算使用的唯一两种比较方法。其他要求引用ConvexHull类实例维护的内部状态数据。我最初的解决方案(显然完全有效)有不属于任何类的方法。取而代之的是,所有的状态数据和比较函数都在一个全局匿名名称空间中,但这破坏了我项目的线程安全性,所以我决定走这条路

如果你复制并粘贴到一个空的项目,你应该看到我得到的错误。它说我需要使用.*或->*作为成员函数指针。然而,尝试这样做会给我带来其他错误,说这些函数不能用作成员函数,因为它们属于“未解析重载函数”类型

如果结果证明我不能这样做,我应该如何最好地实现std::sort和std::unique,使传递给它们的比较函数使用函数本身定义之外的状态数据,而不使用全局变量违反线程安全性?我以前的解决方案是:

namespace {
  Vec2 point0; // state data that other comparison functions like
               // bottomRight and vecEqual need
  bool bottomRight(/*...*/){/*...*/}
  bool vecEqual(/*...*/){/*...*/}
}

// Accesses global data. Bad!
Polygon chGrahamScan(std::vector<Vec2> points) {
  std::sort(points.begin(),points.end(),bottomRight);
  std::vector<Vec2>::iterator it;
  it = std::unique(points.begin(),points.end(),vecEqual);
  // etc..
}
名称空间{
Vec2 point0;//表示其他比较函数喜欢的数据
//最底层的权利和平等的需要
布尔右下(/*…*/){/*…*/}
布尔向量相等(/*…*/){/*…*/}
}
//访问全局数据。糟糕!
多边形chGrahamScan(标准::向量点){
std::sort(points.begin()、points.end()、bottomRight);
std::vector::it迭代器;
it=std::unique(points.begin()、points.end()、vecEqual);
//等等。。
}

正如编译器所说,将函数设为静态并使用作用域运算符:

class ConvexHull {
public:
   // Used to sort an array of vectors so the bottom-right element is first:
   static bool bottomRight(const Vec2& a, const Vec2& b);
   // Used to determine if coordinates are equivalent:
   static bool vecEqual(const Vec2& a, const Vec2& b);
   Polygon chGrahamScan(std::vector<Vec2> points);
};
...
std::sort(points.begin(),points.end(),ConvexHull::bottomRight); // !!!Does not compile!!!
class ConvxHull{
公众:
//用于对向量数组进行排序,使右下角元素位于第一位:
静态布尔右下角(常数向量2&a、常数向量2&b);
//用于确定坐标是否相等:
静态布尔向量相等(常数向量2&a、常数向量2&b);
多边形chGrahamScan(标准::矢量点);
};
...
排序(points.begin()、points.end()、ConvexHull::bottomRight);/!!!不编译!!!

如果要将排序函数与比较器一起使用,请将比较器作为单独的对象编写,而不是将代码放在ConvexHull类中。除非您需要ConvexHull中的一些私有数据,否则您的comparator不需要是该类的一部分

class ConvexHull
{
    // ... rest of class as shown above ...
    private:
       // declare friend so comparator can use private data.
        friend struct VectorComparator;
};

struct VectorComparator
{
    explicit VectorComparator( ConvexHull * hull ) : hull_( hull ) {}
    bool operator()( const Vec2& a, const Vec2& b ) const
    {
        // ... compare the two Vec2 objects here using private data from ConvexHull ...
    }
    ConvexHull * hull_;
};
然后您可以使用
vectorcomarator
作为std::sort的参数

ConvexHull * hull = new ConvexHull;
std::sort(points.begin(),points.end(), VectorComparator(hull) );
您可以为独特的功能制作一个单独的比较器

struct UniqueVectorComparator
{
    bool operator()( const Vec2& a, const Vec2& b ) const
    {
        // .. compare the two Vec2 objects here.
    }
};

it = std::unique(points.begin(),points.end(), UniqueVectorComparator() );

你试过了吗?我可能不太理解C++库。然后我是否将该类传递给std::sort/std::unique而不是函数指针?是的,传递比较器实例而不是函数指针。谢谢,这似乎正是我需要的解决方案!我知道bottomRight和vecEqual在概念上不需要状态数据,但我有其他的比较函数。特别是我有一个名为anglePoint0()的命令,它根据点相对于某个点的角度对点进行排序,该点是ConvexHull的数据成员。如果比较函数是静态的,它们如何访问该数据成员?@GarrettGutierrez如果它们是ConvexHull中的静态函数,则比较函数无法访问数据成员。我可以通过编辑我的答案向您展示一种方法。@GarrettGutierrez存在指向实例的函数成员的指针,但您不能在没有实例的情况下调用它们(使用运算符。*或->*)