5

Questo codice è un test semplificato per qualcosa che sto cercando di fare altrove. Ho una funzione che accetta un argomento "ref-to-ptr" e lo modifica per restituire un puntatore da un elenco di puntatori.L'assegnazione da un costitutore const_iterator può causare un comportamento non definito?

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

typedef int* intp; 
typedef std::list<intp> intplist; 
intplist myList; 

void func(intp &arg) // (1) 
{ 
    intplist::const_iterator it = myList.begin(); 
    std::advance(it, 2); 
    arg = *it; 
} 

int main() 
{ 
    myList.push_back(new int(1)); 
    myList.push_back(new int(2)); 
    myList.push_back(new int(3)); 

    int* ip = NULL; // (2) 
    func(ip); 
    if (ip) cout << "ip = " << *ip << endl; 
    else cout << "ip is null!" << endl; 

    for (intplist::const_iterator it = myList.begin(); it != myList.end(); ++it) 
     delete *it; 
    return 0; 
} 

Funziona e stampe ip = 3 come previsto, solo io sono preoccupato che possa causare un comportamento non definito o comunque portare a problemi, perché sto strappando via la costanza del iteratore assegnando il risultato di esso è dereferenziazione a l'argomento. Ho provato ad aggiungere const a (1) e (2) ma non è stato creato.

Ho ragione di essere preoccupato? In tal caso, perché non ricevo un avviso da g ++ (4.9.2)?

+1

"Ho provato ad aggiungere const a (1) e (2) ma non ha generato.": Hai fatto anche tu aggiungi 'const' a' intp' typedef? – Petr

+0

No ... Ho trattato il typedef come una stupida macro di sostituzione di una stringa e ho appena inserito il const nella dichiarazione 'func':' void func (const intp & arg) '. A modo tuo, costruisce e funziona, ma non capisco qual è la differenza. – neuviemeporte

+0

'intp' è un puntatore. 'const intp' è un puntatore costante, non dice nulla sulla costanza del valore a cui punta. Quando dici 'typedef const int * intp', dici che punterà a un intero const. – Petr

risposta

5

Il codice è perfettamente a posto. Non stai strappando via alcuna costanza (non c'è modo di farlo implicitamente in C++). *it ti dà un const intp &. È il che copia il puntatore a cui fa riferimento tale riferimento in arg. Copiare da qualcosa non toglie la costanza. L'assegnazione a arg assegna a ip nel tuo caso, non è bind legare nulla all'oggetto intp all'interno del contenitore.

+0

Se sto leggendo questo correttamente, questo significa che '* it' è" riferimento a un puntatore a const int ". Com'è possibile che io sia in grado di assegnarlo a 'val', che è" riferimento a puntatore a int "(non-const)? – neuviemeporte

+0

OK, penso di capire ora - è "const riferimento a pointer-to-int", giusto? Il puntatore non è mai stato const. – neuviemeporte

+0

@neuviemeporte Sì, è un riferimento a (costante (puntatore a int)) ". Parentesi utilizzate in senso matematico. – Angew

2

const_iterator significa semplicemente che non è possibile assegnare a tale iteratore e/o può solo chiamare le funzioni const sull'oggetto a cui punta. Non c'è alcun problema con la copia dello value - in questo caso un puntatore. Non stai memorizzando i puntatori const, se lo fossi, allora dovresti assegnare a un puntatore const

Problemi correlati