2016-04-04 7 views
0

Der folgende Code ist mein Versuch, die Vereinigung der zwei Elementmenge {2,3} mit der leeren Menge {} zu bilden. Ich erwarte, dass der resultierende Container (in diesem Fall eine Liste) sollte Größe 2 haben.Das Bilden der Vereinigung von zwei Mengen scheint falsche und inkonsistente Antworten zu geben

Wenn ich jedoch den Code ausführen, bekomme ich, dass die Größe der Union 0 oder 3 ist, je nachdem, welche der beiden angegebene Orte für die Deklaration der Variablen united. Keines dieser Ergebnisse ist das, was ich erwartet habe und sie können eindeutig nicht beide richtig sein.

Was fehlt mir hier?

#include <list> 
#include <set> 
#include <algorithm> 
#include <iostream> 

using namespace std; 

int main() 
{ 
    //list<int> united; // resulting output is 3 

    int d1[] = {2,3}; 
    set<int> dom1(d1, d1+2); 
    set<int> dom2; 

    list<int> united; // resulting output is 0 

    set_union(dom1.begin(), dom1.end(), dom2.begin(), dom2.end(), united.begin()); 

    cout << united.size(); 

    return 0; 
} 

Antwort

3

Wenn Sie einen Blick auf die Dokumentation von std::set_union nehmen Sie werden feststellen, dass die fünfte Iterator die Anforderungen der OutputIterator erfüllen müssen.

Dann, wenn Sie einen Blick auf die Dokumentation von std::list::begin nehmen, werden Sie feststellen, dass es eine std::list::iterator (or std::list::const_iterator) zurückgibt, die nur ein BidirectionalIterator ist, die ein Subtyp von InputIterator ist.

Technisch gesehen ist ein nicht konstanter InputIterator auch ein OutputIterator, der sich jedoch so verhält, dass er für Ihr Programm nicht funktioniert. Es iteriert die Knoten von united und kopiert die Quellelemente über die bereits vorhandenen. Aber da united in Ihrem Fall leer ist, geht der Iterator außerhalb der Grenzen, was zu undefiniertem Verhalten führt.

Eine einfache Möglichkeit, einen OutputIterator zu erhalten, der neue Elemente einfügt, ist die Verwendung des std::back_inserter.

2

Wenn Sie "falsche und inkonsistente Antworten" erhalten, haben Sie im Allgemeinen undefiniertes Verhalten oder Ihr Programm ist anderweitig schlecht ausgebildet, ohne diagnostiziert worden zu sein. Suchen Sie nach Fehlern außerhalb des Bereichs.

Hier bezieht sich Ihr Ausgabe-Iterator auf einen Bereich, der nicht existiert.

Sie sollten united.begin() durch std::back_inserter(united) ersetzen, damit Elemente nach Bedarf erstellt werden.

Dies ist für das Beispiel in the cppreference.com std::set_union documentation.
Lesen Sie die Dokumentation!