2010-04-26 14 views
8

ich eine Klasse Headerdatei habe Grid.h genannt, die das folgende zwei private Datenobjekt enthält:C++ Vektor von Vektoren

vector<int> column; 
vector<vector<int>> row; 

Und eine öffentliche Methode, dessen Prototyp in Grid.h ist so:

int getElement (unsigned int& col, unsigned int& row); 

die Definition der oben genannten Funktion als solche in Grid.cpp definiert:

int getElement (unsigned int& col, unsigned int& row) 
{ 
    return row[row][col] ; 
} 

Wenn ich das Programm laufen lasse, erhalte ich diese Fehler:

error C2109: subscript requires array or pointer type 

Was läuft falsch?

+3

Gibt es Gründe, Sie nehmen diese Parameter als Referenz? Wenn überhaupt, sollten sie eine konstante Referenz sein, aber grundsätzlich sollten grundlegende Typen nicht als Referenz weitergegeben werden, es sei denn, Sie benötigen sie. Warum auch zwei Vektoren? Der Vektor innerhalb eines Vektors ist beides, Ihr 'Spalten'-Vektor ist nur etwas anderes. – GManNickG

Antwort

17

In der Zeile return row[row][col]; ist die erste row die int&, nicht die vector.

Die Variablen in dem inneren Gültigkeitsbereich deklariert werden, um die Variable in dem äußeren Umfang Abschattung, so dass die Compiler zu indizieren versuchen ein int eher als ein vector, die es offensichtlich nicht tun kann.

Sie sollten Ihre Variablennamen korrigieren, damit sie nicht in Konflikt stehen.

EDIT: Auch während der Fehler, die Sie zeigt immer, dass der Compiler die falsche row Variable zu finden, wie A. Levy weist darauf hin, Sie haben auch ein Problem mit der Erklärung Ihrer vector, so auch Wenn Sie die Variablennamen korrigieren, wenn Sie tatsächlich die vector wie hier gezeigt deklariert haben, wird es nicht kompilieren. Verschachtelte Templates benötigen Leerzeichen zwischen den > Symbolen, ansonsten wird der Compiler >> als Rechtsverschiebeoperator statt als Teil einer Template-Deklaration lesen. Es braucht

std::vector<std::vector<int> > row; 

oder

std::vector< std::vector<int> > row; 

Zusätzlich zu sein, wie Sie dies in einer Header-Datei zu tun sind, Sie gehen zu dem std::-Tag auf der Vorderseite etwas brauchen, um tack aus der Namespace std - wie vector. Wenn es in einer CPP-Datei ist, dann könnte man using namespace std; verwenden, aber das wäre sehr schlecht in einer Header-Datei zu tun (da sie den globalen Namensraum verschmutzen würde). Ohne den std::-Tag oder die using-Anweisung erkennt der Compiler vector nicht. Dies ist

+0

Wenn ich den Namen der Vektoren in horizontal und vertikal ändern, bekomme ich nicht deklarierte Bezeichner Fehler für jede von ihnen – xbonez

+0

Alternativ können Sie einfach "this-> row [row] [col]" und es sollte funktionieren. –

8

wahrscheinlich nicht der Index Problem, aber Sie müssen auch einen Raum zwischen den verschachtelten spitzen Klammern in Ihrem Vektor von Vektoren Typdeklaration. C++ - Compiler haben es schwer, den Unterschied zwischen verschachtelten Template-Typen und dem richtigen Bit-Shift-Operator zu erkennen.

Beispiel:

vector<vector<int> > vec2d;  // Good. 

vector<vector<int>> anotherVec2d; // Bad! 

vector< vector<int> > yetAgain;  // Best IMHO. 
            // Keeps the white space balanced. 
+9

@KevenK, ein Leerzeichen zwischen den beiden Symbolen hindert den Compiler daran, sie als einen Operator zu behandeln. Ich wünschte, ich könnte deinen Kommentar ablehnen. –

+3

Platz ist in diesem Fall sehr wichtig. Der Parser verwendet maximales Munch zum Parsen, so dass er das größtmögliche Token ergreift. Das bedeutet, dass in 'vector >' '' 'als Shift-Operator statt als Teil einer Template-Deklaration analysiert wird. Sie benötigen den zusätzlichen Platz, um dem Compiler anzuzeigen, dass Sie eine Vorlage deklarieren, und nicht einen Ausdruck mit einem Verschiebungsoperator. –

+3

Dies wurde jetzt geändert. Wenn Sie einen aktuellen Compiler verwenden, können Sie wahrscheinlich "vector >" schreiben und bekommen, was Sie erwarten. Noch nicht Standard, aber VS2010, g ++ und fast sicher andere unterstützen es jetzt. –

1

Es scheint mir (obwohl Sie diese auf eigene Faust müssen, um zu überprüfen, ich fühle mich nicht wie eine Testanwendung zu schreiben nach oben), dass das Problem aus der Tatsache kommt, dass Ihr Parameter enthält einen Namen row und Ihre Klasse hat eine innere Variable row und es gibt einen Namenskonflikt.

Möglicherweise müssen Sie sich für die von Ihnen verwendete Zeile qualifizieren.Bedenken Sie:

return Grid::row[row][col]; 
+0

Oder return this-> row [row] [col] – a1ex07

+0

Ich habe Zeile und Spalte im privaten Bereich in horizontale und vertikale umbenannt. Ich bekomme jetzt den Fehler 'horizontal: nicht deklarierte Kennung' und 'vertikal: nicht deklarierte Kennung' – xbonez

+0

@xbonez: Warum haben Sie zwei Vektoren? Ich dachte du wolltest einen Vektor von Vektoren? (Geben Sie einen 2D-Vektor.) – GManNickG

4

Ich glaube, Sie so etwas wie dies wollen ... (obwohl ich nicht, warum :-) vorstellen kann)

#include <vector> 
#include <iostream> 

using namespace std; 

typedef vector<int> row; 
typedef vector<row> matrix; 

matrix mat(2,2); 

int getElement (unsigned int ri, unsigned int ci) 
{ 
    return mat[ri][ci] ; 
} 

int main() { 

    mat[1][0] = 1234; 
    cout << getElement(1,0) << endl; 

    return 0; 
} 
+0

aahhh !! Ja, das scheint viel besser zu sein. Ich habe nicht daran gedacht. Auf diese Weise muss ich keine Vektoren verschachteln. Danke vielmals. Ich werde es so benutzen. – xbonez

+0

Diese Antwort verschachtelt immer noch Vektoren, nur unter einem C-style typedef Alias, der nicht mit Vorlagen kompatibel ist ... –

3

Dies ist, was Sie brauchen:

return Grid::row[row][col]; 
Verwandte Themen