5 Stimmen

For-Schleifen auf Basis von Bereichen in C++

Es scheint, dass der in C++11 verfügbare "for each"-Syntax die Array-Iteration ohne Kenntnis der tatsächlichen Größe des Arrays (Anzahl der Elemente) ermöglicht. Ich gehe davon aus, da es Teil des neuen Standards ist, dass dies perfekt sicher ist, selbst für C-Arrays. Typischerweise müssen Sie auch separat die Größe eines C-Arrays kennen, bevor Sie es manipulieren, aber ich möchte Bestätigung von jemandem, der Erfahrung mit dieser neuen C++-Technik hat, dass sie genauso funktioniert, wie Sie es erwarten:

extern float bunch[100];

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

Gibt es etwas, was ich über nicht offensichtliche Nebeneffekte oder Nachteile dieser Technik wissen sollte? In dem von mir gesehenen Code ist nicht viel sichtbar, wahrscheinlich weil der Großteil des Codes geschrieben wurde, bevor dies im Standard war. Möchte sicherstellen, dass die seltene Verwendung nicht aufgrund eines anderen nicht gut bekannten Grundes erfolgt.

4voto

juanchopanza Punkte 216358

Es ist nichts Seltsames oder Unsicheres an dieser Verwendung. Die Größe des Arrays ist zur Kompilierzeit bekannt, daher kann es in der Schleife verwendet werden. Dies ist ein Beispiel für eine Vorlagenfunktion, mit der Sie die Länge eines Arrays ermitteln können:

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

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

Dies sollte klarstellen, dass Sie diese Technik oder Schleifenbereiche nicht bei dynamisch dimensionierten C-Style-Arrays verwenden können.

Natürlich sollten Sie, wenn Sie Schleifenbereiche haben, auch std::array haben (falls nicht, können Sie es wahrscheinlich von std::tr1 oder boost erhalten), damit Sie das C-Style-Array vollständig vermeiden können:

extern std::array bunch;

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

4voto

Nikos C. Punkte 48846

Es ist völlig sicher, eine Range-basierte for-Schleife mit Arrays zu verwenden. Ich vermute, Sie machen sich Sorgen, dass Sie sie versehentlich auf einen Zeiger anwenden könnten:

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

Keine Sorge jedoch. In diesem Fall wird der Compiler einen Fehler produzieren. Also in Fällen, in denen es nicht sicher ist, erhalten Sie sowieso einen Kompilierungsfehler.

2voto

TemplateRex Punkte 67281

Arrays können als Referenzen übergeben werden und ihr Typ und ihre Länge werden abgeleitet.

#include 

template
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 }; // hier keine Länge angeben
   fun(x); // 1 2 3, hier keine Typ- und Längenangabe erforderlich
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X