Saya mengulangi vektor dan membutuhkan indeks iterator saat ini menunjuk. AFAIK ini dapat dilakukan dengan dua cara:
it - vec.begin()
std::distance(vec.begin(), it)
Apa pro dan kontra dari metode ini?
c++
iterator
coding-style
cairol
sumber
sumber
it
?std::container_type::iterator it;
std::list
tidak menawarkan akses langsung ke elemen berdasarkan posisi mereka, jadi jika Anda tidak dapat melakukannyalist[5]
, Anda seharusnya tidak dapat melakukannyalist.begin() + 5
.Saya lebih suka
std::distance(vec.begin(), it)
karena akan memungkinkan saya untuk mengubah wadah tanpa perubahan kode. Misalnya, jika Anda memutuskan untuk menggunakanstd::list
alih-alihstd::vector
yang tidak memberikan iterator akses acak, kode Anda masih akan dikompilasi. Karena std :: distance mengambil metode optimal tergantung pada sifat iterator Anda tidak akan mengalami penurunan kinerja.sumber
vec
adalah berita buruk. Jika kode tersebut ditulis ulang menjadi generik, dengan menggunakan tipe wadah sebagai parameter templat, saat itulah kita dapat (dan harus) berbicara tentang penanganan iterator non-akses acak ;-)vec
juga berita buruk.Seperti yang ditunjukkan UncleBens dan Naveen, ada alasan bagus untuk keduanya. Yang mana yang "lebih baik" tergantung pada perilaku apa yang Anda inginkan: Apakah Anda ingin menjamin perilaku waktu-konstan, atau Anda ingin kembali ke waktu linier bila diperlukan?
it - vec.begin()
membutuhkan waktu yang konstan, tetapioperator -
hanya didefinisikan pada iterator akses acak, jadi kode tidak akan dikompilasi sama sekali dengan iterator daftar, misalnya.std::distance(vec.begin(), it)
bekerja untuk semua jenis iterator, tetapi hanya akan menjadi operasi waktu konstan jika digunakan pada iterator akses acak.Tidak ada yang "lebih baik". Gunakan yang melakukan apa yang Anda butuhkan.
sumber
Saya suka yang ini:,
it - vec.begin()
karena bagi saya itu jelas mengatakan "jarak dari awal". Dengan iterator kita terbiasa berpikir dalam hal aritmatika, jadi-
tandanya adalah indikator yang paling jelas di sini.sumber
distance
?it++
dan bukan sesuatu seperti itustd::increment(it)
, bukan? Bukankah itu juga dianggap kurang jelas?++
Operator didefinisikan sebagai bagian dari urutan STL bagaimana kita kenaikan iterator.std::distance
menghitung jumlah elemen antara elemen pertama dan terakhir. Fakta bahwa-
operator bekerja hanyalah sebuah kebetulan.Jika Anda sudah dibatasi / hardcode algoritma Anda untuk menggunakan a
std::vector::iterator
danstd::vector::iterator
hanya, tidak masalah metode mana yang Anda akan gunakan. Algoritme Anda sudah dikonkretkan melampaui titik di mana memilih satu dari yang lain dapat membuat perbedaan. Mereka berdua melakukan hal yang persis sama. Ini hanya masalah preferensi pribadi. Saya pribadi akan menggunakan pengurangan eksplisit.Sebaliknya, jika Anda ingin mempertahankan tingkat umum yang lebih tinggi dalam algoritme Anda, yaitu, untuk memungkinkan kemungkinan bahwa suatu hari di masa depan itu dapat diterapkan ke beberapa jenis iterator lain, maka metode terbaik tergantung pada niat Anda. . Itu tergantung pada seberapa ketat Anda ingin berkaitan dengan jenis iterator yang dapat digunakan di sini.
Jika Anda menggunakan pengurangan eksplisit, algoritme Anda akan dibatasi untuk kelas iterator yang agak sempit: iterator akses-acak. (Ini adalah apa yang Anda dapatkan sekarang dari
std::vector
)Jika Anda menggunakan
distance
, algoritma Anda akan mendukung kelas iterator yang lebih luas: input iterator.Tentu saja, menghitung
distance
untuk iterator non-akses-acak pada umumnya merupakan operasi yang tidak efisien (sementara, sekali lagi, untuk akses-acak itu seefisien pengurangan). Terserah Anda untuk memutuskan apakah algoritma Anda masuk akal untuk iterator non-acak-akses, efisiensi-bijaksana. Jika kerugian yang dihasilkan dalam efisiensi sangat menghancurkan hingga membuat algoritma Anda sama sekali tidak berguna, maka Anda sebaiknya tetap berpegang pada pengurangan, sehingga melarang penggunaan yang tidak efisien dan memaksa pengguna untuk mencari solusi alternatif untuk jenis iterator lainnya. Jika efisiensi dengan iterator non-akses acak masih dalam rentang yang dapat digunakan, maka Anda harus menggunakandistance
dan mendokumentasikan fakta bahwa algoritma ini bekerja lebih baik dengan iterator akses acak.sumber
Menurut http://www.cplusplus.com/reference/std/iterator/distance/ , karena
vec.begin()
merupakan iterator akses acak , metode jarak menggunakan-
operator.Jadi jawabannya adalah, dari sudut pandang kinerja, itu sama, tetapi mungkin menggunakan
distance()
lebih mudah untuk dipahami jika ada yang harus membaca dan memahami kode Anda.sumber
Saya akan menggunakan
-
varianstd::vector
hanya - cukup jelas apa yang dimaksud, dan kesederhanaan operasi (yang tidak lebih dari pengurangan pointer) diekspresikan oleh sintaks (distance
, di sisi lain, terdengar seperti pythagoras pada bacaan pertama, bukan?). Seperti yang ditunjukkan oleh UncleBen, ini-
juga bertindak sebagai pernyataan statis jikavector
suatu kasus diubah secara tidak sengajalist
.Juga saya pikir ini jauh lebih umum - tidak ada angka untuk membuktikannya. Argumen utama:
it - vec.begin()
lebih pendek dalam kode sumber - lebih sedikit pekerjaan mengetik, lebih sedikit ruang yang digunakan. Karena jelas bahwa jawaban yang tepat untuk pertanyaan Anda menjadi masalah selera, ini juga bisa menjadi argumen yang valid.sumber
Berikut adalah contoh untuk menemukan "semua" kejadian 10 beserta indeksnya. Kupikir ini akan sangat membantu.
sumber