Perché non riesco a creare un vettore di riferimenti?

Quando faccio questo:

std::vector hello; 

Tutto funziona alla grande. Tuttavia, quando lo faccio un vettore di riferimenti, invece:

 std::vector hello; 

Ottengo errori orribili come “errore C2528: ‘puntatore’: puntatore al riferimento è illegale”.

Voglio mettere una serie di riferimenti alle strutture in un vettore, in modo da non dover interferire con i puntatori. Perché il vettore sta facendo i capricci di questo? La mia unica opzione è usare un vettore di puntatori?

Il tipo di componente di contenitori come i vettori deve essere assegnabile . I riferimenti non sono assegnabili (è ansible inizializzarli solo una volta quando vengono dichiarati e non è ansible farli riferire qualcos’altro in un secondo momento). Altri tipi non assegnabili non sono ammessi come componenti di contenitori, ad esempio il vector non è consentito.

sì, puoi cercare std::reference_wrapper , che simula un riferimento ma è assegnabile e può anche essere “riposizionato”

Per loro stessa natura, i riferimenti possono essere impostati solo nel momento in cui vengono creati; cioè, le seguenti due linee hanno effetti molto diversi:

 int & A = B; // makes A an alias for B A = C; // assigns value of C to B. 

Futher, questo è illegale:

 int & D; // must be set to a int variable. 

Tuttavia, quando crei un vettore, non c’è modo di assegnare valori agli oggetti durante la creazione. Stai essenzialmente facendo un sacco di esempi.

Ion Todirel ha già menzionato una risposta utilizzando std::reference_wrapper . Dal momento che C ++ 11 abbiamo un meccanismo per recuperare oggetti da std::vector e rimuovere il riferimento usando std::remove_reference . Di seguito viene fornito un esempio compilato usando g++ e clang con l’opzione
-std=c++11 ed eseguito con successo.

 #include  #include  #include class MyClass { public: void func() { std::cout << "I am func \n"; } MyClass(int y) : x(y) {} int getval() { return x; } private: int x; }; int main() { std::vector> vec; MyClass obj1(2); MyClass obj2(3); MyClass& obj_ref1 = std::ref(obj1); MyClass& obj_ref2 = obj2; vec.push_back(obj_ref1); vec.push_back(obj_ref2); for (auto obj3 : vec) { std::remove_reference::type(obj3).func(); std::cout << std::remove_reference::type(obj3).getval() << "\n"; } } 

boost::ptr_vector funzionerà.

Modifica: era un suggerimento per usare std::vector< boost::ref > , che non funzionerà perché non puoi build in modo predefinito un boost::ref .

È un difetto nel linguaggio C ++. Non è ansible prendere l’indirizzo di un riferimento, poiché il tentativo di farlo comporterebbe l’indirizzo dell’object a cui si fa riferimento, e quindi non si può mai ottenere un puntatore a un riferimento. std::vector funziona con i puntatori ai suoi elementi, quindi i valori che si stanno memorizzando devono poter essere puntati. Dovrai invece usare i puntatori.

Come altri hanno già detto, probabilmente finirai per utilizzare un vettore di puntatori.

Tuttavia, potresti prendere in considerazione l’uso di un ptr_vector !

Come suggeriscono gli altri commenti, si è limitati a utilizzare i puntatori. Ma se aiuta, ecco una tecnica per evitare di affrontare direttamente i puntatori.

Puoi fare qualcosa di simile al seguente:

 vector iarray; int default_item = 0; // for handling out-of-range exception int& get_item_as_ref(unsigned int idx) { // handling out-of-range exception if(idx >= iarray.size()) return default_item; return reinterpret_cast(*iarray[idx]); }