Pertanyaan rentang berbasis untuk loop di c ++


Tampaknya bahwa "untuk masing-masing" gaya sintaks yang tersedia di C + + 11 memungkinkan pengulangan array tanpa pengetahuan tentang ukuran sebenarnya dari array (jumlah elemen). Saya berasumsi, karena ini adalah bagian dari standar baru, bahwa ini sangat aman, bahkan untuk C array. Biasanya, Anda juga harus secara terpisah mengetahui ukuran susunan C sebelum memanipulasinya, tetapi saya ingin verifikasi dari siapa pun yang berpengalaman dengan teknik C ++ baru ini yang berfungsi persis seperti yang Anda harapkan:

extern float bunch[100];

for (float &f : bunch) {
  f += someNumber;
}

Adakah yang harus saya ketahui tentang efek samping yang tidak jelas atau kerugian pada teknik ini? Itu tidak menunjukkan banyak dalam kode yang saya lihat, mungkin karena sebagian besar kode ditulis sebelum ini dalam standar. Ingin memastikan penggunaannya yang langka bukan karena alasan lain yang tidak dikenal.


5
2018-01-21 13:35


asal


Jawaban:


Tidak ada yang aneh atau tidak aman tentang penggunaan itu. Ukuran array diketahui pada waktu kompilasi, sehingga dapat digunakan dalam loop. Ini adalah contoh fungsi template yang memungkinkan Anda untuk mengetahui panjang array:

template< class T, std::size_t N >
std::size_t length( const T (&)[N] )
{
  return N;
}

Foo f[5];
std::cout << length(f) << "\n";

Ini harus menjelaskan bahwa Anda tidak dapat menggunakan teknik ini, atau rentang loop berbasis, pada array C-style berukuran dinamis.

Tentu saja, jika Anda memiliki loop berdasarkan rentang maka Anda juga harus memiliki std::array (jika tidak, Anda mungkin bisa mendapatkan ti dari std::tr1 atau dorong), sehingga Anda dapat menghindari susunan C-style sepenuhnya:

extern std::array<float, 100> bunch;

for (auto &f : bunch) {
  f += someNumber;
}

4
2018-01-21 13:41



Sangat aman untuk menggunakan for-loop berbasis array dengan array. Saya kira Anda khawatir bahwa Anda mungkin secara tidak sengaja menggunakannya pada penunjuk:

float* array = new float[100];
for (float& f : array) {
    // ...
}

Tapi jangan khawatir. Compiler akan menghasilkan kesalahan dalam kasus ini. Jadi dalam kasus-kasus di mana tidak aman, Anda akan mendapatkan kesalahan kompilasi.


4
2018-01-21 13:46



Array dapat dilewatkan sebagai referensi dan memiliki tipe dan panjangnya disimpulkan.

#include <iostream>

template<typename T, size_t N>
void fun(T const (&arr)[N])
{
    for (std::size_t i = 0; i < N; ++i)
       std::cout << arr[i] << " ";
}

int main()
{
   int x[] = { 1, 2, 3 }; // no need to set length here
   fun(x); // 1 2 3, no need to specify type and length here
}

2
2018-01-21 13:37