Казалось бы, синтаксис «для каждого», доступный в C ++ 11, разрешает итерацию массива без знания фактического размера массива (количества элементов). Я предполагаю, что, поскольку это является частью нового стандарта, это совершенно безопасно, даже для массивов Си. Как правило, вы также должны отдельно знать размер массива C, прежде чем манипулировать им, но я хочу, чтобы любой, кто имел опыт работы с этой новой техникой C ++, проверял, что она работает точно так, как вы ожидаете:
extern float bunch[100];
for (float &f : bunch) {
f += someNumber;
}
Что я должен знать о неочевидных побочных эффектах или недостатках этой техники? В коде, который я вижу, ничего особенного нет, вероятно, потому, что большая часть кода была написана до того, как это было в стандарте. Хотите убедиться, что его редкое использование не по какой-то другой причине, не известной.
В этом использовании нет ничего странного или небезопасного. Размер массива известен во время компиляции, поэтому его можно использовать в цикле. Это пример функции шаблона, которая позволяет вам узнать длину массива:
template< class T, std::size_t N >
std::size_t length( const T (&)[N] )
{
return N;
}
Foo f[5];
std::cout << length(f) << "\n";
Это должно прояснить, что вы не можете использовать эту технику или циклы, основанные на диапазоне, для динамически изменяемых массивов в стиле C.
Конечно, если у вас есть петли, основанные на диапазоне, то вы должны также иметь std::array
(если нет, вы можете получить std::tr1
или повысить), так что вы можете полностью избежать массива в стиле C:
extern std::array<float, 100> bunch;
for (auto &f : bunch) {
f += someNumber;
}
Совершенно безопасно использовать основанный на диапазоне цикл for с массивами. Я полагаю, вы беспокоитесь, что можете случайно использовать его на указателе:
float* array = new float[100];
for (float& f : array) {
// ...
}
Не беспокойся, хотя. Компилятор выдаст ошибку в этом случае. Так что в тех случаях, когда это небезопасно, вы все равно получите ошибку компиляции.
Массивы могут быть переданы как ссылки, и их тип и длина выводятся.
#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
}