Berikut ini tidak mengkompilasi:
#include <iostream>
int main()
{
int a{},b{},c{},d{};
for (auto& s : {a, b, c, d}) {
s = 1;
}
std::cout << a << std::endl;
return 0;
}
Kesalahan kompiler adalah: error: assignment of read-only reference 's'
Sekarang dalam kasus saya yang sebenarnya daftar dibuat dari variabel anggota di kelas.
Sekarang, ini tidak berfungsi karena ekspresi menjadi initializer_list<int>
yang benar-benar menyalin a, b, c, dan d - karenanya juga tidak memungkinkan modifikasi.
Pertanyaan saya ada dua:
Apakah ada motivasi di balik tidak memungkinkan untuk menulis rentang berbasis untuk loop dengan cara ini? misalnya. mungkin ada kasus khusus untuk ekspresi penyangga telanjang.
Apa cara rapi dan rapi untuk memperbaiki jenis loop ini?
Sesuatu di sepanjang garis ini akan lebih disukai:
for (auto& s : something(a, b, c, d)) {
s = 1;
}
Saya tidak menganggap pointer tipuan solusi yang baik (yaitu {&a, &b, &c, &d}
) - solusi apa pun harus memberikan referensi elemen secara langsung ketika iterator dide-referensi .
sumber
{ &a, &b, &c, &d }
.initializer_list
sebagian besar tampilan padaconst
array.{ &a, &b, &c, &d }
, Anda tidak akan menginginkan keduanya:for (auto& s : std::initializer_list<std::reference_wrapper<int>>{a, b, c, d}) { s.get() = 1; }
Jawaban:
Kisaran tidak sesihir yang orang inginkan. Pada akhirnya, harus ada objek yang dapat dikompilasi oleh kompiler ke fungsi anggota atau fungsi bebas
begin()
danend()
.Yang terdekat Anda mungkin bisa datang adalah:
sumber
std::vector<int*>
.auto s
atauauto* s
tidakauto& s
.Hanya solusi lain dalam ide pembungkus:
Kemudian:
output
sumber
Menurut standar §11.6.4 Daftar-inisialisasi / p5 [dcl.init.list] [ Tambang Penekanan ]:
Dengan demikian, kompiler Anda mengeluh secara sah (yaitu,
auto &s
dikurangkanint const& s
dan Anda tidak dapat menetapkannyas
dalam rentang untuk loop).Anda bisa mengatasi masalah ini dengan memperkenalkan wadah alih-alih daftar penginisialisasi (mis. `Std :: vector ') dengan' std :: reference_wrapper ':
Demo Langsung
sumber
for (auto& s : {a, b, c, d})
tidak bekerja. Mengenai mengapa standar memiliki klausa itu ..... Anda harus bertanya kepada anggota komite standardisasi. Seperti banyak hal lain, alasannya bisa antara "Kami tidak menganggap kasus khusus Anda cukup berguna untuk diganggu" hingga "Terlalu banyak bagian standar yang harus diubah untuk mendukung kasus Anda, dan kami menunda pertimbangan semua itu sampai kita mengembangkan standar masa depan ".std::array<std::reference_wrapper>>
?Untuk memenuhi sintaks itu
Anda dapat membuat pembungkus:
Demo
sumber
std::reference_wrapper
?std::reference_wrapper
akan membutuhkans.get() = 1;
.Solusi: gunakan pembungkus referensi
Kemudian digunakan sebagai:
Ini tidak mencoba menjawab pertanyaan pertama.
sumber
Anda bisa membuat kelas pembungkus untuk menyimpan referensi dan yang akan memiliki operator penugasan untuk memperbarui nilai ini:
Demo langsung
sumber