zweidimensionales vector Array in structur Variable deklarieren



  • Hallo zusammen,

    als Newbie brauche ich einmal eure Hilfe.
    Ich möchte mir eine structur Variable machen, in der ich ein zweidimensional Feld aus zwei vectoren deklariere.
    bekomme aber immer eine Fehlermeldung, dass das so nicht geht.
    Es wird angezeigt, dass ich eine Funktion daraus erstellen kann, aber ich möchte nur ein Attribute damit deklarieren.
    Quasi

    char Arr[ROW][COLUMN];
    

    Auch beim Initialisieren dieser im Konstruktor bin ich mir unsicher, ob das so geht.

    #define ROW 13
    #define COLUMN 15
    
    using namespace std;
    
    typedef struct {
    	string name;
    	vector<vector<char>> field(ROW, vector<char>(COLUMN));         //Fehler
    }map;
    
    class Spiel
    {	
    private:	
    	map theMap;
    
    public:
    	Spiel()
           {	
                    theMap.name = "";
    	                for (auto i = 0; i < ROW; i++)	{
    		             for (auto j = 0; j < COLUMN; j++)	{
    			            theMap.field[i][j] = ' ';
    		             } 
    	                }
            }
    

    Vielen Dank für eure Hilfe! LG



  • Davon abgesehen, dass gleich die ersten Antworten kommen, dass man für ein 2D array, wie du es haben willst, kein vector von einem vector nimmt:

    struct map{
       string name;
       vector<vector<char>> field;       
    };
    
    Spiel()
    {	
        theMap.name = "";
        for (auto i = 0; i < ROW; i++){
            theMap.field.push_back(vector<char>());
            for (auto j = 0; j < COLUMN; j++)	{
                theMap.field[i].push_back(' ');
            } 
         }	                
    }
    

    Merke, ich habe die mehr c++ Artige Deklaration eines structs verwendet.

    Du kannst einem Strukt auch ein Konstruktor verpassen:

    constexpr int ROW = 10; 
    constexpr int COLUMN = 10;
    using namespace std;
    struct map{
        map(string aName, std::vector<vector<char> > aField):name(std::move(aName)), field(std::move(aField)){}
        string name;
        vector<vector<char>> field;    
    };
    
    class Spiel
    {	
    private:	
        map theMap;
    
    public:
        Spiel(): theMap("", vector<vector<char>> (ROW, std::vector<char>(COLUMN, ' ')))
        {}
    };
    

    Oder so kannst du ein Strukt auch initialisieren:

    constexpr int ROW = 10; 
    constexpr int COLUMN = 10;
    using namespace std;
    
    struct map{
        string name;
        vector<vector<char>> field;       
    };
    
    class Spiel
    {	
    private:	
       map theMap;
    
    public:
       Spiel(): theMap({"", vector<vector<char>> (ROW, std::vector<char>(COLUMN, ' '))})
    {}
    };
    

    Ich hoffe, ich habe beim schnellen tippen nichts übersehen, ist immerhin Freitag morgens;)
    Für weitere Fragen ist es immer hilfreich, die genaue Fehlermeldung via Copy&Paste hier zu posten und ein kompilierfähiges Beispiel zu posten (inklusive includes und allem was dazu gehört).



  • Aus welchem Grund hast du den vector in der Struktur drin? Brauchst du das Ding öfter?

    Grundsätzlich erscheint es mir sinnvoll, den vector(2d) in eine eigenen Klasse zu tun:

    class Field
    {
    public:
         Field( unsigned rows_, unsigned columns_ ) : Cells( rows_, std::vector<char>( columns_, 0 ) ) {}
    
    private:
        std::vector<std::vector<char>> Cells;
    }
    
    

    Habs nicht kompiliert, aber so in der Art.

    Die DEFINEs sind definitiv unnötig.



  • Noch ein Hinweis zum Naming: ich würde dir einen anderen Namen als "map" empfehlen. Es gibt in der STL die Klasse std::map - und unter einer Map versteht man in der Regel die Zuordnung von Schlüsseln auf Werte (nennt sich manchmal auch "Dictionary").

    Und zum Kommentar von @Schlangenmensch

    Davon abgesehen, dass gleich die ersten Antworten kommen, dass man für ein 2D array, wie du es haben willst, kein vector von einem vector nimmt:

    Genau! Problem ist: ein vector<vector<...>> garantiert dir nicht, dass jede Zeile gleich viele Spalten hat. Außerdem liegen die Daten des gesamten Feldes in Anzahl Zeilen möglicherweise verschiedenen Speicherbereichen, also nicht zusammenhängend. Daher empfiehlt es sich meistens, stattdessen nur einen vector<...> zu erstellen mit der Länge zeilen*spalten.



  • Bei einem Array mit konstanten Dimensionen sollte man wohl eher std::array<T> benutzen...



  • @wob sagte in zweidimensionales vector Array in structur Variable deklarieren:

    Daher empfiehlt es sich meistens, stattdessen nur einen vector<...> zu erstellen mit der Länge zeilen*spalten.

    Das hier unterschreibe ich. Mach das(!). Das spart dir jede Menge krampfigen Fummelcode. Warum die geschachtelten Schleifen zur Initialisierung wenn es auch einfach sowas hier tut?:

    field(zeilen * spalten, ' ')
    

    Zugriff geht z.B. elegant mit ()-Operator:

    #include <iostream>
    #include <vector>
    
    struct Map
    {
        int width;
        int height;
        std::vector<char> field;
    
        Map(int width, int height, char value = ' ')
        : width{ width }, height{ height }, field(height * width, value)
        {
        }
    
        auto operator()(int i, int j) const -> char
        {
            return field[i * width + j];
        }
    
        auto operator()(int i, int j) -> char&
        {
            return field[i * width + j];
        }
    };
    
    auto main() -> int
    {
        Map m{ 10, 10, '.' };
        m(3, 3) = 'x';
        m(5, 0) = 'x';
        m(0, 5) = 'x';
        for (int i = 0; i < m.height; ++i)
        {
            for (int j = 0; j < m.width; ++j)
                std::cout << m(i, j);
            std::cout << "\n";
        }
        return 0;
    }
    

    https://ideone.com/4JSQix



  • Vielen vielen Dank für die aufschlussreichen Infos und vor Allem Erklärungen ! Das hat mir sehr geholfen.
    Das mit der Fehlermeldung merke ich mir und ergibt Sinn, werde ich in zukünftigen Post berücksichtigen.

    Hatte schon Angst, ich bekomme hier auf den Deckel, aber sehr freundliche und konstruktive Antworten. Das habe ich hier in anderen Beiträgen schon anders gesehen.

    DANKE DANKE DANKE! - ich kann weitermachen!
    Wünsche allen noch ein schönes Wochenende!



  • Ergänzung:

    @Mais sagte in zweidimensionales vector Array in structur Variable deklarieren:

    typedef struct {
    string name;
    vector<vector<char>> field(ROW, vector<char>(COLUMN)); //Fehler
    }map;

    Mit {} statt () würde deine Originalversion mit einem aktuellen Compiler ohne Fehlermeldung übersetzen:

    typedef struct {
    	string name;
    	vector<vector<char>> field{ROW, vector<char>(COLUMN)};        
    }map;
    


  • using namespace std;
    
    typedef struct {
    	string name;
    	vector<vector<char>> field(ROW, vector<char>(COLUMN));         //Fehler
    }map;
    

    Schlechte idee. std hat bereits eine eigene Klasse (bzw. ein Klassentemplate) namens map.



  • @Mais sagte in zweidimensionales vector Array in structur Variable deklarieren:

    Hatte schon Angst, ich bekomme hier auf den Deckel, aber sehr freundliche und konstruktive Antworten. Das habe ich hier in anderen Beiträgen schon anders gesehen.

    Der Hauptunterschied ist, dass du Quellcode gepostet hast, über den man sprechen kann. Völlig egal ob der gut oder schlecht ist. Die meisten anderen, die hier etwas unsanft geweckt werden, posten hier ihre Hausaufgabe und fertig. Darauf reagieren einige allergisch oder gar pampig.


Log in to reply