Kann std :: mit Array-Parametern arbeiten und wenn ja, wie?

8

Ich habe Probleme mit std::begin() und std::end() (aus der iterator -Bibliothek) mit c-style Array-Parametern.

%Vor%

Dies führt zu dem folgenden Fehler mit Visual Studio 2010 (und ähnlich für Ende):

%Vor%

Das Ändern des Parameters in non-const ergibt dasselbe Ergebnis.

Versuchen Sie, den Parameter als

anzugeben %Vor%

Gibt:

%Vor%

Ist es nicht möglich, std::begin für Array-Parameter zu verwenden, weil sie zu Zeigern zerfallen? Gibt es einen Trick, um dies zu umgehen oder ist es am besten, die Iterator-Funktionen für Array-Parameter nicht zu verwenden?

    
A.E. Drew 18.11.2013, 22:47
quelle

5 Antworten

14

Ja, std::begin und std::end können mit Parametern arbeiten, die Arrays im C-Stil sind.

Der Trick besteht darin, einen Parameter zu übergeben, der ein C-artiges Array ist. Wenn Sie ein 1D-Array als normalen Parameter für eine normale Funktion angeben, wird dessen Typ still von "Array von T" zu "Pointer to T" angepasst. Wenn Sie diese Funktion aufrufen, wird nicht das Array (als Array) übergeben, sondern ein Zeiger auf das erste Element des Arrays.

Es ist jedoch möglich, ein Array durch Verweis auf eine Funktionsvorlage zu übergeben:

%Vor%

In dieser Fall, wo Sie ein tatsächliches Array (wenn auch durch Referenz) statt einen Zeiger übergeben, können Sie std::begin und std::end perfekt verwenden. Zum Beispiel:

%Vor%

Das Übergeben eines Arrays ist nun trivial wie:

%Vor%

std::begin und std::end selbst werden ähnlich wie sum implementiert - das Array wird als Referenz übergeben, sodass sie in etwa so aussehen können:

%Vor%

Beachten Sie, dass diese, obwohl sie dem Standard in jüngerer Zeit hinzugefügt wurden, keine besonders knifflige Verwendung von Templates erfordern. Daher sollte die obige Implementierung mit einem einfachen alten C ++ 98-Compiler funktionieren (und, wenn der Speicher dient, sogar mit Vor-Standard-Compilern wie VC ++ 6).

    
Jerry Coffin 18.11.2013, 22:58
quelle
4

Beachten Sie zunächst, dass die Parameterdeklaration const double i_point[3] absolut const double* i_point entspricht. Das heißt, die Funktion nimmt jeden Zeiger unabhängig von der Anzahl der angezeigten Elemente auf double const . Als Ergebnis weiß es nicht die Größe und std::begin() und std::end() kann die Größe nicht ableiten (naja, std::begin() muss die Größe sowieso nicht wirklich ableiten).

Wenn du wirklich std::begin() und std::end() benutzen willst, musst du ein Array mit drei Elementen oder einen Verweis auf ein solches Biest übergeben. Da Sie Arrays nicht nach Wert übergeben können, ist es am besten, wenn Sie sie als Referenz übergeben:

%Vor%

Diese Funktion akzeptiert nur Arrays mit genau drei Elementen als Argumente: Sie können keinen Zeiger auf drei double s oder einen Teil eines größeren Arrays übergeben. Im Gegenzug können Sie nun std::begin() und std::end() verwenden.

    
Dietmar Kühl 18.11.2013 22:52
quelle
1
%Vor%

ist dasselbe wie

%Vor%

oder

%Vor%

Also, std::begin und std::end können das nicht akzeptieren. In C ++ können Sie ein Array nicht übergeben, sondern als Zeiger oder Verweis. Wenn es ein Zeiger ist, dann trägt es keine Informationen des übergebenen Arrays.

Ihre Alternativen sind std::vector oder std::array .

    
deepmax 18.11.2013 22:49
quelle
0

Hast du std :: array angesehen?

Es funktioniert besser mit anderen STL-Komponenten

    
Glenn Teitelbaum 18.11.2013 22:52
quelle
0

Während Sie Ihre Frage nicht direkt beantworten (sie wurde bereits ausreichend von M. M. und Dietmar Kühl ), scheinen Sie einige std::vector in dieser Funktion zu initialisieren. Das heißt, warum nicht einfach:

%Vor%

Anstelle eines Funktionsaufrufs an Ihre Funktion, die dies versucht?

Alternativ könnten Sie Ihre Funktion wie folgt schreiben:

%Vor%

und rufe es dann mit:

%Vor%     
Zac Howland 18.11.2013 22:58
quelle

Tags und Links