массивы — основанные на диапазоне для циклов в переполнении стека

Казалось бы, синтаксис «для каждого», доступный в C ++ 11, разрешает итерацию массива без знания фактического размера массива (количества элементов). Я предполагаю, что, поскольку это является частью нового стандарта, это совершенно безопасно, даже для массивов Си. Как правило, вы также должны отдельно знать размер массива C, прежде чем манипулировать им, но я хочу, чтобы любой, кто имел опыт работы с этой новой техникой C ++, проверял, что она работает точно так, как вы ожидаете:

extern float bunch[100];

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

Что я должен знать о неочевидных побочных эффектах или недостатках этой техники? В коде, который я вижу, ничего особенного нет, вероятно, потому, что большая часть кода была написана до того, как это было в стандарте. Хотите убедиться, что его редкое использование не по какой-то другой причине, не известной.

5

Решение

В этом использовании нет ничего странного или небезопасного. Размер массива известен во время компиляции, поэтому его можно использовать в цикле. Это пример функции шаблона, которая позволяет вам узнать длину массива:

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;
}
4

Другие решения

Совершенно безопасно использовать основанный на диапазоне цикл for с массивами. Я полагаю, вы беспокоитесь, что можете случайно использовать его на указателе:

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

Не беспокойся, хотя. Компилятор выдаст ошибку в этом случае. Так что в тех случаях, когда это небезопасно, вы все равно получите ошибку компиляции.

4

Массивы могут быть переданы как ссылки, и их тип и длина выводятся.

#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
По вопросам рекламы [email protected]