Ketika saya melakukan ini:
std::vector<int> hello;
Semuanya bekerja dengan baik. Namun, ketika saya menjadikannya sebagai vektor referensi:
std::vector<int &> hello;
Saya mendapatkan kesalahan mengerikan seperti
kesalahan C2528: 'pointer': pointer ke referensi adalah ilegal
Saya ingin meletakkan banyak referensi untuk struct ke dalam vektor, sehingga saya tidak perlu ikut campur dengan pointer. Mengapa vektor membuat ulah tentang ini? Apakah satu-satunya pilihan saya untuk menggunakan vektor pointer?
Jawaban:
Jenis komponen wadah seperti vektor harus dialihkan . Referensi tidak dapat ditugaskan (Anda hanya dapat menginisialisasi sekali ketika mereka dideklarasikan, dan Anda tidak dapat membuatnya referensi lain nanti). Jenis lain yang tidak dapat ditentukan juga tidak diizinkan sebagai komponen wadah, misalnya
vector<const int>
tidak diizinkan.sumber
ya Anda bisa, mencari
std::reference_wrapper
, yang meniru referensi tetapi dapat ditugaskan dan juga dapat "diulang"sumber
get()
pertama ketika mencoba mengakses metode instance kelas di wrapper ini? Misalnyareference_wrapper<MyClass> my_ref(...); my_ref.get().doStuff();
tidak seperti referensi..get()
. Yang diinginkan timdiels adalahoperator.
; lihat proposal / diskusi terbaru tentang itu.Sesuai sifatnya, referensi hanya dapat ditetapkan pada saat mereka dibuat; yaitu, dua baris berikut memiliki efek yang sangat berbeda:
Lebih lanjut, ini ilegal:
Namun, saat Anda membuat vektor, tidak ada cara untuk menetapkan nilai pada item-item itu saat dibuat. Anda pada dasarnya hanya membuat sejumlah contoh terakhir.
sumber
Ion Todirel sudah menyebutkan jawaban yang YA gunakan
std::reference_wrapper
. Karena C ++ 11 kami memiliki mekanisme untuk mengambil objek daristd::vector
dan menghapus referensi dengan menggunakanstd::remove_reference
. Di bawah ini diberikan contoh dikompilasi menggunakang++
danclang
dengan opsi-std=c++11
dan berhasil dijalankan.sumber
std::remove_reference<>
sini. Intinyastd::remove_reference<>
adalah untuk memungkinkan Anda menulis "tipe T, tetapi tanpa menjadi referensi jika itu salah satu". Jadistd::remove_reference<MyClass&>::type
sama saja dengan menulisMyClass
.for (MyClass obj3 : vec) std::cout << obj3.getval() << "\n";
(ataufor (const MyClass& obj3: vec)
jika Anda mendeklarasikangetval()
const, sebagaimana mestinya).boost::ptr_vector<int>
akan bekerja.Sunting: adalah saran untuk digunakan
std::vector< boost::ref<int> >
, yang tidak akan berfungsi karena Anda tidak dapat membuat-default aboost::ref
.sumber
resize
.Ini cacat dalam bahasa C ++. Anda tidak dapat mengambil alamat referensi, karena mencoba melakukannya akan menghasilkan alamat objek yang dirujuk, dan dengan demikian Anda tidak akan pernah bisa mendapatkan pointer ke referensi.
std::vector
bekerja dengan pointer ke elemen-elemennya, sehingga nilai-nilai yang disimpan harus dapat ditunjukkan. Anda harus menggunakan pointer sebagai gantinya.sumber
sizeof
referensi juga.TL; DR
Gunakan
std::reference_wrapper
seperti ini:Demo
Jawaban panjang
Seperti yang disarankan standar , untuk wadah standar yang
X
berisi objek bertipeT
,T
harusErasable
dariX
.Erasable
berarti ungkapan berikut terbentuk dengan baik:A
adalah tipe pengalokasi penampung,m
adalah pengalokasi contoh danp
merupakan penunjuk tipe*T
. Lihat di sini untukErasable
definisi.Secara default,
std::allocator<T>
digunakan sebagai pengalokasi vektor. Dengan pengalokasi default, persyaratannya setara dengan validitasp->~T()
(Perhatikan,T
ini adalah tipe referensi danp
penunjuk ke referensi). Namun, penunjuk ke suatu referensi adalah ilegal , oleh karena itu ungkapannya tidak terbentuk dengan baik.sumber
Seperti yang telah disebutkan, Anda mungkin akan menggunakan vektor pointer saja.
Namun, Anda mungkin ingin mempertimbangkan menggunakan ptr_vector sebagai gantinya!
sumber
Seperti komentar lain menyarankan, Anda terbatas menggunakan pointer. Tetapi jika itu membantu, berikut adalah satu teknik untuk menghindari berhadapan langsung dengan petunjuk.
Anda dapat melakukan sesuatu seperti berikut ini:
sumber
reinterpret_cast
tidak diperlukan