사용자 정의 비교기를 사용하여 C ++에서 priority_queue 선언


88

(노드 클래스 외부에있는) 비교기 함수로 priority_queue of nodes사용 하여을 선언하려고합니다 bool Compare(Node a, Node b).

내가 현재 가지고있는 것은 :

priority_queue<Node, vector<Node>, Compare> openSet;

어떤 이유에서인지 나는 Error: "Compare" is not a type name

선언을 다음으로 변경 priority_queue <Node, vector<Node>, bool Compare>

나에게 준다 Error: expected a '>'

나는 또한 시도했다 :

priority_queue<Node, vector<Node>, Compare()> openSet;
priority_queue<Node, vector<Node>, bool Compare()> openSet;
priority_queue<Node, vector<Node>, Compare<Node, Node>> openSet; 

올바르게 신고하려면 어떻게해야 priority_queue합니까?

답변:


113

다음과 같이 클래스를 선언 Compare하고 오버로드 해야 operator()합니다.

class Foo
{

};

class Compare
{
public:
    bool operator() (Foo, Foo)
    {
        return true;
    }
};

int main()
{
    std::priority_queue<Foo, std::vector<Foo>, Compare> pq;
    return 0;
}

또는 어떤 이유로 클래스로 만들 수없는 경우 다음과 같이 사용할 수 있습니다 std::function.

class Foo
{

};

bool Compare(Foo, Foo)
{
    return true;
}

int main()
{
    std::priority_queue<Foo, std::vector<Foo>, std::function<bool(Foo, Foo)>> pq(Compare);
    return 0;
}

1
완벽 해, 내가 찾던 바로 그것. 별도의 수업을 만들 생각은 없었습니다. 첫 번째 예가 더 나은 스타일로 간주 될까요?
Steven Morad 2013

2
@StevenMorad, 나는 오버로드 된 클래스를 사용하는 것을 선호합니다 operator().
awesoon

1
@soon 연산자 ()를 오버로드하는 이유는 무엇입니까? 이것이 priority_queues가 내부적으로 구현되는 방식과 관련이 있습니까? 오버로딩> 또는 <는 직관적으로 이해되지만 () 연산자는 그다지 많지 않습니다
Piyush

2
@Piyush, 질문은 사용자 지정 비교기를 pritority_queue. operator<내장 된 std::less비교기 를 오버로드 하고 사용할 수 있지만 질문에 따라 bool Compare(Node a, Node b)클래스 외부 에서 선언 Node됩니다.
awesoon

3
내가 구문을 기억할 수 없다, 지금 아마 50 배처럼,이 답변에 돌아 오는 유지
Rockstar5645

52

허용되는 대답은 클래스 std::function또는를 비교기로 사용해야한다고 믿게합니다 . 이것은 사실이 아닙니다! cute_ptr의 답변 에서 알 수 있듯이 함수 포인터를 생성자에 전달할 수 있습니다. 그러나 이렇게하는 구문은 여기에 표시된 것보다 훨씬 간단합니다.

class Node;
bool Compare(Node a, Node b);

std::priority_queue<Node, std::vector<Node>, decltype(&Compare)> openSet(Compare);

즉, 함수의 유형을 명시 적으로 인코딩 할 필요가 없습니다. 컴파일러가 decltype.

이것은 비교기가 람다 인 경우 매우 유용합니다. 를 사용하는 것 이외의 다른 방법으로 람다의 유형을 지정할 수 없습니다 decltype. 예를 들면 :

auto compare = [](Node a, Node b) { return a.foo < b.foo; }
std::priority_queue<Node, std::vector<Node>, decltype(compare)> openSet(compare);

2
이것은 환상적입니다. 여기에 잠재적 인 함정 (문제)이 있는지 궁금합니다. 이 답변이 더 많은 가시성과 토론을 얻을 수 있기를 바랍니다.
Apollys는 Monica

1
@Apollys :이 메서드를 정기적으로 사용합니다 (보통 Compare람다로 선언을 작성할 수 없습니다). 트랩에 대해 잘 모릅니다.
Cris Luengo

람다 함수에 대해이 작업을 수행하려면 람다 함수의 본문을 어디에 넣겠습니까? 당신은 그것을 변수에 저장겠습니까 f사전에 다음 교체 Compare와 함께 f?
에릭 올드

@EricAuld : 예, Compare에서와 같이 람다 함수가 될 수 있습니다 auto Compare = [](){};. 그러나 decltype(Compare)대신 을 사용해야 decltype(&Compare)합니다.
Cris Luengo

안녕하세요 Chris, 이것은 훌륭합니다. priority_queue에 decltype과 함께 사용할 형식을 찾고 있었고 클래스를 선언하지 않고 완벽한 답을주었습니다! 감사!
Amanda Wang

17

세 번째 템플릿 매개 변수는 operator()(Node,Node)오버로드 된 클래스 여야합니다 . 따라서 다음과 같이 클래스를 만들어야합니다.

class ComparisonClass {
    bool operator() (Node, Node) {
        //comparison code here
    }
};

그런 다음이 클래스를 다음과 같이 세 번째 템플릿 매개 변수로 사용합니다.

priority_queue<Node, vector<Node>, ComparisonClass> q;

14
운영자 방법은 공용이어야합니다.
knezi

1
세 번째 템플릿은 클래스 일 필요가 없습니다. 함수의 유형이 될 수 있습니다.
Cris Luengo

1
cpluplus 에 따르면 : 이것은 함수 포인터 또는 함수 객체
Benav

9

질문에 직접 답변 :

다음을 priority_queue사용하여 노드 를 선언하려고합니다.bool Compare(Node a, Node b) as the comparator function

내가 현재 가지고있는 것은 :

priority_queue<Node, vector<Node>, Compare> openSet;

어떤 이유로 오류가 발생합니다.

"Compare" is not a type name

: 컴파일러는 잘못 정확히 무엇을 말하고 Compare되지 않은 유형 이름 만 두를 취하는 함수의 인스턴스 Nodes와를 반환합니다 bool.
필요한 것은 함수 포인터 유형을 지정하는 것입니다.
std::priority_queue<Node, std::vector<Node>, bool (*)(Node, Node)> openSet(Compare)


이것이 priority_queue 선언에 함수를 제공하기 위해 찾고있는 것입니다. 감사합니다!
Amanda Wang

6

람다 함수를 사용할 수도 있습니다.

auto Compare = [](Node &a, Node &b) { //compare };
std::priority_queue<Node, std::vector<Node>, decltype(Compare)> openset(Compare);

6

먼저 비교를 정의해야합니다. 이를 수행하는 세 가지 방법이 있습니다.

  1. 수업 사용
  2. struct 사용 (클래스와 동일)
  3. 람다 함수를 사용하십시오.

선언하기 쉽기 때문에 클래스 / 구조체를 사용하기 쉽습니다. 실행 코드 위에이 코드 줄을 작성하기 만하면됩니다.

struct compare{
  public:
  bool operator()(Node& a,Node& b) // overloading both operators 
  {
      return a.w < b.w: // if you want increasing order;(i.e increasing for minPQ)
      return a.w > b.w // if you want reverse of default order;(i.e decreasing for minPQ)
   }
};

전화 코드 :

priority_queue<Node,vector<Node>,compare> pq;

@shivam Mishra 지점까지.
fight_club

3

이것이 누구에게나 도움이되는 경우 :

static bool myFunction(Node& p1, Node& p2) {}
priority_queue <Node, vector<Node>, function<bool(Node&, Node&)>> pq1(myFunction);

0

구조체를 선호하고 std :: greater가하는 일입니다.

struct Compare {
  bool operator()(Node const&, Node &) {}
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.