Vettore di oggetti const che danno errore di compilazione

Ho dichiarato quanto segue nel mio codice

vector  mylist; 

Ottengo il seguente errore di compilazione –

 new_allocator.h:75: error: `const _Tp* __gnu_cxx::new_allocator::address(const _Tp&) const \[with _Tp = const A]' and `_Tp* __gnu_cxx::new_allocator::address(_Tp&) const [with _Tp = const A]' cannot be overloaded 

Ma se dichiari –

 vector  mylist; 

il mio codice viene compilato

Const non è permesso in questo contesto?

Sto copiando il mio codice qui per tutti i riferimenti –

 #include  #include  using namespace std; class A { public: A () {cout << "default constructor\n";} A (int i): m(i) {cout << "non-default constructor\n";} private: int m; }; int main (void) { vector mylist; mylist.push_back(1); return 0; } 

Gli elementi di un vettore devono essere assegnabili (o, nelle versioni più recenti dello standard, mobili). const oggetti const non sono assegnabili, quindi il tentativo di memorizzarli in un vettore fallirà (o almeno può fallire – il codice non è valido, ma un compilatore è libero di accettarlo comunque, se così preferisce, anche se la maggior parte dei programmatori generalmente preferisco che il codice non valido venga rifiutato).

Suppongo che per il vero pedante, se volessi abbastanza male, potresti definire un tipo che è stato assegnabile nonostante sia const , qualcosa del genere:

 class ugly { mutable int x; public: ugly const &operator=(ugly const &u) const { x = ux; return *this; } }; 

Anche se questo ha fallito con alcuni compilatori più vecchi (ad esempio, gcc 4.8.1) funziona con quelli attuali, credo che dovresti essere in grado di memorizzare elementi di questo tipo in un vector anche se sono const . Un rapido test per creare un vettore di questi successi con VC ++. Ciò non ha funzionato con alcuni compilatori più vecchi (ad esempio, non è riuscito con g ++ 4.8.1), ma funziona con quelli ragionevolmente recenti (VC ++ almeno fino al 2015, g ++ torna almeno a 5.4 e clang ++ torna ad almeno 4.0 – sebbene io non abbia ” t ho cercato di rintracciare la prima versione di ciascuno che l’ha supportata).

L’uso del metodo push_back è il problema. emplace_back verrà compilato. Un’altra alternativa (a seconda dell’intera situazione non descritta qui) sarebbe quella di utilizzare un vector se gli elementi inseriti hanno una vita al di fuori del vettore. Gli elementi in un vettore non devono essere assegnabili, ma quando non lo sono, alcune funzioni membro e algoritmi non possono essere utilizzati.

Spiegazione :

push_back dovrebbe inizialmente build un valore A nel vettore, quindi assegnare (usando il costrutto di copia) il riferimento dato. Questo interrompe la qualifica const , quindi non viene compilata.

emplace_back utilizza “forwarding perfetto” per invocare direttamente il costruttore effettivo.