1

Ich verwende eine STL priority_queue und geben Sie eine benutzerdefinierte Komparator-Klasse, deren Konstruktor den Zeiger auf den Vektor übernimmt, der die Prioritäten speichert, so -Fehler: Anforderung für Mitglied '..' in '..', die von Nicht-Klassen-Typ ist

#include <iostream> 
#include <queue>   // std::priority_queue 
#include <vector>   // std::vector 

using namespace std; 

class CompareReachDist 
{ 
    const vector<float> *reach_dists; 
public: 
    CompareReachDist(const vector<float> *input) 
    { 
     reach_dists = input; 
    } 

    bool operator() (const size_t &l, const size_t &r) const 
    { 
     return (reach_dists->at(l) > reach_dists->at(r)); 
    } 
}; 

typedef priority_queue<size_t, vector<size_t>, CompareReachDist> pq; 
vector<float> reach_dists; 

int main() 
{ 
    pq seeds(CompareReachDist(&reach_dists)); 
    bool isEmpty = seeds.empty(); 

    return 0; 
} 

jedoch zum Kompilieren erhalte ich die Fehlermeldung:

error: request for member 'empty' in 'seeds', which is of non-class type 'pq(CompareReachDist&) {aka std::priority_queue<unsigned int std::vector<unsigned int>, CompareReachDist>(CompareReachDist&)}' 

Wo ich falsch gehe?

Antwort

3

Dies ist ein Parsing-Problem. Sagen wir es auseinander brechen:

CompareReachDist(&reach_dists) 

Sie mögen denken, dies eine temporäre CompareReachDist mit der Adresse des statischen reach_dists erzeugt. Im Rahmen der Gesamterklärung wird dies jedoch als Bezugnahme auf eine CompareReachDist interpretiert. Seltsam, aber das ist, weil, grob gesagt, die Grammatik von C++ Funktionsdeklarationen zur Objektdeklaration bevorzugt. Die folgenden

pq seeds(CompareReachDist(&reach_dists)); 

Ist eine allgemeine Erklärung einer Funktion. Es akzeptiert eine CompareReachDist& und gibt eine pq zurück.

Der Fehler, den Sie erhalten, liegt daran, dass eine Funktion offensichtlich keinen empty Member hat, den Sie anrufen können.

Die Lösung seit C++ 11 ist die Begünstigung der Listeninitialisierung, die die Mehrdeutigkeit und ihre Auflösung als Funktionsdeklaration unterbricht. So können Sie dies tun:

pq seeds{CompareReachDist{&reach_dists}}; 

Und bekommen Sie ein Objekt, wie man es erwarten würde.

+0

Ah, ja. Ich sehe es jetzt. Wie denken Sie, sollte ich meine Objektdeklaration so umstrukturieren, dass der Compiler sie nicht mehr für eine Funktionsdeklaration verwendet? –

+0

@ ameya.dubey - Nun, bevorzugen Sie C++ 11 Initialisierungssyntax. Oder führen Sie eine benannte Variable für den Parameter 'CompareReachDist' ein. – StoryTeller

+0

@ ameya.dubey - Tatsächlich tust du es. Freut mich, Ihnen behilflich zu sein. – StoryTeller

Verwandte Themen