2017-01-14 1 views
4

Ich muss STL :: Satz von Strukturen erstellen. Ich schreibeSo erstellen Sie std :: Satz von Strukturen

stl::set <Point> mySet; //Point - name of structure 

Aber dann versuche ich eine Struktur Instanz hinzufügen

Point myPoint; 
mySet.insert(myPoint); 

Es gibt mehrere Kompilierungsfehlern (Fehler C2784, C2676 Fehler) MYSET. Jemand kann einen Rat geben?

1> C: \ Program Files (x86) \ Microsoft Visual Studio 10.0 \ VC \ include \ xfunctional (125): Fehler C2784: bool std :: operator < (const std :: vector < _Ty, _AX > &, const std :: vector < _Ty, _AX> &): failed das Argument zu einer Vorlage "const std :: vector < _Ty, _AX> &" von "const Point"

1> C zu bringen: \ Programme (X 86) \ Microsoft Visual Studio 10.0 \ VC \ include \ xfunctional (125): Fehler C2676: Binär "<": "const Point" definiert diesen Operator oder eine Konvertierung in einem für das Integrieren akzeptablen Typen nicht d-Operator

+0

Nun, es ist 'std :: set'. 'C2784' und' C2676' ergeben keinen Sinn. Wir brauchen die eigentliche Nachricht. Haben Sie auch sichergestellt, dass 'struct Point' 'operator <' 'implementiert? 'std :: set' benötigt es. – DeiDei

+1

Definieren Sie einen 'Operator <' für Ihre 'Point'-Struktur. – void

Antwort

7

Die Vorlage std::set stellt einen assoziativen Container bereit, der einen sortierten Satz eindeutiger Objekte enthält. Die Schlüsselwörter sind sortiert und einzigartig. Zur Unterstützung der Sortierung ergeben sich eine Reihe von Möglichkeiten, die letztlich jedoch zu einer Übereinstimmung mit strict weak ordering führen müssen. Das zweite Template-Argument zu std::set ist ein Vergleich Typ. Der Standardwert std::less<Key> wird von der Standardbibliothek bereitgestellt, wobei Key der Objekttyp ist, den Sie in Ihrem Container speichern (in Ihrem Fall Point). Dieser Standard erzeugt einfach einen Vergleich unter Verwendung aller zulässigen verfügbaren operator <, die den Schlüsseltyp unterstützen. Das bedeutet, eine oder andere Weise, wenn Sie den Standard Komparator (std::less<Point> in Ihrem Fall) verwenden, dann nehme an Operationen wie diese Klasse muss:

Point pt1(args); 
Point pt2(args); 

if (pt1 < pt2) // <<=== this operation 
    dosomething(); 

Mehrere Methoden, dies zu tun unten erscheinen:

ein Mitglied bieten operator <

bei weitem einfachste Methode, dies zu erreichen, ist ein Mitglied operator < für Ihre Point-Klasse zu bieten. Dabei wird pt1 < pt2 gültig und std::less<Point> ist dann glücklich. Angenommen, Ihre Klasse ist ein traditionelles x, y Punkt, würde es so aussehen:

struct Point 
{ 
    int x,y; 

    // compare for order.  
    bool operator <(const Point& pt) const 
    { 
     return (x < pt.x) || ((!(pt.x < x)) && (y < pt.y)); 
    } 
}; 

Geben Sie eine benutzerdefinierte Komparatortyp

Eine andere Methode wäre eine Art benutzerdefinierte Komparator zur Verfügung zu stellen, anstatt verlassen sich auf std::less<Point>. Der größte Vorteil dabei ist die Fähigkeit, mehrere zu definieren, die unterschiedliche Dinge bedeuten können, und sie in Containern oder Algorithmen zu verwenden, wenn dies erforderlich ist.

struct CmpPoint 
{ 
    bool operator()(const Point& lhs, const Point& rhs) const 
    { 
     return (lhs.x < rhs.x) || ((!(rhs.x < lhs.x)) && (lhs.y < rhs.y)); 
    } 
}; 

Damit können Sie jetzt Ihre std::set wie folgt erklären:

std::set<Point,CmpPoint> mySet; 

Etwas mit diesem Ansatz zu berücksichtigen: Die Art ist nicht Teil der Point, so dass jeder Zugriff auf private Member-Variablen oder Funktionen muss in befristeter Form durch Friesen ausgeglichen werden.


stellen eine freie-Funktion operator <

Einen weiteren seltenen Mechanismus ist einfach eine globale Frei Funktion zur Verfügung stellen, die operator < bietet. Dies ist KEINE Mitgliedsfunktion. Dadurch wird der Standardwert std::less<Point> wieder zu einem gültigen Code führen.

bool operator <(const Point& lhs, const Point& rhs) 
{ 
    return (lhs.x < rhs.x) || ((!(rhs.x < lhs.x)) && (lhs.y < rhs.y)); 
} 

Dies kann eine Mischung aus scheinen sowohl den benutzerdefinierten Komparator und dem Element-Operator, und in der Tat viele der Vor-und Nachteile der einzelnen kommen. Bsp .: wie das Mitglied operator <, können Sie einfach den Standard std::less<Point> verwenden. Wie der benutzerdefinierte Vergleicher ist dies eine Nicht-Klassen-Funktion, so dass der Zugriff auf private Mitglieder über Freunde oder Zugriffsmethoden bereitgestellt werden muss.


Zusammenfassung

Für Ihre Bedürfnisse, würde ich mit dem einfachen Ansatz gehen; mach einfach ein Mitglied operator <. Wahrscheinlich werden Sie immer Ihre Point s auf diese Weise bestellen wollen. Wenn nicht, gehen Sie mit dem benutzerdefinierten Vergleicher. In entweder Fall machen sicher Sie Ehre strenge schwache Bestellung.

Verwandte Themen