我需要使用自定义比较器的STL排序功能。如果我直接使用比较器函数作为参数进行排序,则会给出非静态方法的错误。所以我创建了一个仿函数。它仍然给出错误: -
class Graph
{
private:
struct edge
{
int src;
int dest;
int weightage;
};
typedef struct edge * edgePtr;
list<edgePtr> edgeList ;
struct compareEdgeWeightage
{
int src, dest, weightage;
bool operator() (list<edgePtr>::iterator edge1ptr , list<edgePtr>::iterator edge2ptr ) const
{
edgePtr edge1 = *edge1ptr;
edgePtr edge2 = *edge2ptr;
return( (edge1->weightage) < (edge2->weightage) ) ;
}
}; //struct compareEdgeWeightage
public:
Graph();
void addEdge(int src, int dest, int weightage);
void MST();
};// class Graph
void Graph::MST()
{
sort( edgeList.begin(),edgeList.end(),compareEdgeWeightage);
} //MST
为了清楚起见,我省略了其他不相关的功能和行。 编译它会给出错误
error: expected primary-expression before ‘)’ token
bash: syntax error near unexpected token `)'
答案 0 :(得分:1)
比较器应该将比较的对象作为参数,而不是迭代器,所以:
bool operator() (edgePtr a, edgePtr b){...}
或者,您也可以使用lambda使代码更紧凑:
sort(edgeList.begin(),edgeList.end(),
[](edgePtr lhs, edgePtr rhs)->bool {
return( (lhs->weightage) < (rhs->weightage) );
});
你的另一个问题是你试图将比较器的类型作为sort
的第三个参数传递,而你应该真正传递一个对象,这样你就可以调用它与
// note that we are creating an object of compareEdgeWeightage here
std::sort(edgeList.begin(), edgeList.end(), compareEdgeWeightage());
或者更好的是,在类中创建一个比较器并使用它来避免创建/复制额外的对象:
class Graph
{
<...>
struct compareEdgeWeightage
{
<...>
}comparator;
};
void Graph::MST()
{
std::sort( edgeList.begin(), edgeList.end(), comparator );
}
你也只需要比较器中的operator()
,这样你就可以摆脱额外的东西:
struct compareEdgeWeightage
{
bool operator() (edgePtr edge1ptr , edgePtr edge2ptr) const
{
return( (edge1ptr->weightage) < (edge2ptr->weightage) ) ;
}
};
然后,最后,std::sort
需要随机访问迭代器才能工作,因此您需要使用列表的内置sort
,幸运的是它支持自定义比较器:
void Graph::MST()
{
edgeList.sort(comparator);
}
答案 1 :(得分:0)
问题是compareEdgeWeightage
是类型,但您需要将该类型的对象传递给std::sort函数。
尝试:
void Graph::MST()
{
std::sort(edgeList.begin(), edgeList.end(), compareEdgeWeightage());
}
您还有其他问题,例如您的std::list
包含指针,而不是迭代器,因此需要这样做:
struct compareEdgeWeightage
{
int src, dest, weightage;
// compare pointers not iterators
bool operator() (edgePtr edge1ptr , edgePtr edge2ptr) const
{
return edge1ptr->weightage < edge2ptr->weightage;
}
};
不幸的是,虽然std::sort不能与std::list
一起使用,因为它需要类似连续容器的东西(实际上是一个提供随机访问迭代器的容器)像std::vector
。
答案 2 :(得分:0)
您需要创建仿函数类的对象,并将其传递给std::sort
。因此代码应如下所示:
std::sort( edgeList.begin(),edgeList.end(),compareEdgeWeightage());
或
compareEdgeWeightage cmp;
std::sort( edgeList.begin(),edgeList.end(),cmp);
如SingerOfTheFall所述,std::sort
将*it1, *it2
作为参数传递给您的仿函数,因此您需要通过值或引用接受参数。一般来说,我会建议使用const引用,但由于edgePtr
只是一个指针,因此值更好。
bool operator() (const edgePtr lhs, const edgePtr rhs) const
{
return lhs->weightage < rhs->weightage
}
顺便说一下,你在函子中不需要int src, dest, weightage;
。它们什么都不做,永远不会被初始化或使用。
以上都不会有所帮助 - 您无法将std::sort
与std::list
一起使用。 std::sort
需要随机访问迭代器,而std::list
仅提供双向迭代器。您需要使用edgeList.sort(..)
最后,无法分辨导致bash错误的原因 - 我们需要查看完整的脚本来解释它。