用于C ++ STL的自定义比较器在')'标记之前排序错误预期为primary-expression

时间:2016-10-21 08:32:42

标签: c++

我需要使用自定义比较器的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 `)'

3 个答案:

答案 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::sortstd::list一起使用。 std::sort需要随机访问迭代器,而std::list仅提供双向迭代器。您需要使用edgeList.sort(..)

最后,无法分辨导致bash错误的原因 - 我们需要查看完整的脚本来解释它。