Domanda

Si consideri il seguente programma. Si crea un insieme di puntatore a int, e usa un comparatore indrect_less personalizzato che ordina il set per il valore della punta-per intero. Una volta fatto questo, ho quindi modificare il valore di uno dei punta-a numeri interi. Poi, si può vedere l'ordine del set non è ordinato (suppongo perché il set non sa cosa ha cambiato).

(non mi dispiace il C ++ 0x loop, sto correndo su VS2010)

#include <iostream>
#include <set>
using namespace std;

struct indirect_less {
    bool operator()(int* l, int* r) const
    {
        return *l < *r;
    }
};

int main()
{
    set<int*, indirect_less> myset;

    int* a = new int(5);
    int* b = new int(6);
    int* c = new int(7);

    myset.insert(a);
    myset.insert(b);
    myset.insert(c);

    cout << "Set contains: ";
    // (outputs: 5 6 7)

    for (auto i = myset.begin(), end = myset.end(); i != end; ++i)
    {
        cout << **i << " ";
    }

    cout << endl << "Modifying *a" << endl;
    *a = 9;         // point of interest
    cout << "Set contains: ";
    // (outputs: 9 6 7 - unsorted order)

    for (auto i = myset.begin(), end = myset.end(); i != end; ++i)
    {
        cout << **i << " ";
    }

    cout << endl;

    cin.get();

    return 0;
}

1) Ho ragione che sto invocando un comportamento indefinito? È l'intero stato del myset invalido dopo la linea *a = 9;?

2) è l'unico modo corretto di fare questo per cancellare reinserire a?

3) C'è un modo, una volta che *a = 9; è stato eseguito, al riequilibrio il set in a modo ordinato, con un comportamento ben definito?

È stato utile?

Soluzione

Sì, std::set assume elementi sono immutabili. E ' possibile , se pericoloso, per riordinare da soli dopo ogni modifica. Io non lo consiglio, però: utilizzare un altro tipo di raccolta.

Altri suggerimenti

1) Sì, insieme non consente la modifica di esso è elementi.

2) Oltre la cancellazione del vecchio valore e inserendo il nuovo valore, si potrebbe anche sostituire il vecchio set con uno di nuova costruzione.

3) No

1) Non so che il comportamento non è definito. La torsione supplementare in questo esempio è che gli elementi dell'insieme non sono alterati - ogni elemento del set è un puntatore. Stavi di stampare gli elementi (puntatore) del set prima e dopo l'esecuzione della linea '* a = 9" , credo che si dovrebbe trovare che i valori puntatore sono nello stesso ordine, prima e dopo l'assegnazione. Quello che è cambiato è il valore che elemento di un insieme di punti. Questo ha avuto luogo al di fuori gli auspici del set, e così il set non ha modo di mantenere l'ordine desiderato.

2) un qualificato "sì". Questo forzerà uso di indirect_less () per ordinare gli elementi dell'insieme. Anche in questo caso, essere consapevoli che si sta ordinando gli elementi del set, puntatori, per il valore di ogni puntatore Dereferenced. Tuttavia, questo mi sembra un po 'rischioso, esattamente per la ragione che descrivi.

Dalla leggenda "Set contiene:" nell'output stampato, presumo che questo esempio si sforza di formare un insieme di numeri interi. Tuttavia, il set definito, vale a dire, "set" in realtà consiste di puntatori a interi, non i numeri interi stessi. Credo che questo disallineamento tra le collezioni desiderate e reali è la causa del problema.

3) V. 2).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top