【问题标题】:How can I use STL sort in c++ to sort some values in the class?如何在 C++ 中使用 STL 排序对类中的某些值进行排序?
【发布时间】:2011-02-28 02:31:26
【问题描述】:

我有一个名为 Graph 的类,在这个类中我有一个名为 V 的成员,它是一个向量。我有一个名为 Edge 的结构和一个 Edge 列表。如下:

struct Edge{
 int u;
 int v;
 Edge(int u,int v){
   this->u=u;
   this->v=v;
 }
};
struct Vertex{
 int d;
 int f;
 .
 .
 .
}

class Graph{
  vector < Vertex > V;
  .
  .
  .
  int edgeCmp(Edge* x,Edge* y){
    return ( V[x->v].d < V[y->v].d )?1:0;
  }
  void someFunction(){
   list<Edge> backEdges;
   backEdges.sort(&Graph::edgeCmp);
  }
}

但它不起作用!有人可以帮我做这样的事情吗?我收到此错误:

错误 3 错误 C2064:术语不计算为采用 2 个参数的函数 c:\program files\microsoft visual studio 9.0\vc\include\xutility 346

它无法理解我正在调用带有 2 个参数的函数。我不知道为什么。

【问题讨论】:

  • 下次使用101010按钮格式化代码。

标签: c++ list sorting


【解决方案1】:

您不能将成员函数用作比较器。成员函数需要 this 指针,该指针不能从 sort 传递。

相反,您必须创建一个函数对象来包含额外信息,例如:

class Graph{
  vector < Vertex > V;

  struct EdgeComparer {
     const vector<Vertex>& V;
     EdgeComparer(const vector<Vertex>& vertices) : V(vertices) {}
     bool operator() (const Edge& a, const Edge& b) const {
        return V[a.v].d < V[b.v].d;
     }
  };

  ...

  EdgeComparer ec (V);
  backEdges.sort(ec);

请注意,由于您有一个Edge 列表,而不是Edge*,因此比较器的输入参数应该Edge*。我已将其更改为const Edge&amp;

【讨论】:

  • 谢谢!有用。但是你可以给我解释一下吗?我不太明白。
  • @Morteza: .sort 可以接受任何可以像f(a,b) 这样调用的对象f。函数是其中一种明显的类型,但具有重载operator() 的类(结构)也是如此。后者称为函数对象。与普通函数相比的优势在于它们可以存储任意状态,就像这里所做的那样——顶点向量V 被包含为函数对象的额外状态,这是比较两个 Edge 所必需的。
【解决方案2】:
return (V[x->v].dv].d)?1:0;

这条线有不平衡的括号,读起来很糟糕(我怀疑前者是后者的结果)。如果没有看到您的 Vertex 类,很难说出它应该做什么 - 在修复括号之后,也许您应该重新格式化以提高可读性。

【讨论】:

  • 我添加了 Vertex 结构,但事实并非如此。我收到这样的错误:术语不评估为采用 2 个参数的函数
  • @Morte 尝试将edgeCmp 声明为static。此外,您应该将返回类型更改为 bool 并删除 ?1:0 部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-26
  • 1970-01-01
  • 2011-02-11
  • 1970-01-01
  • 2011-02-15
相关资源
最近更新 更多