2009-03-01 17 views
0

Ich habe eine statische Zuordnung der ID < => Struct-Paare, und jede Struktur sollte einige Arrays enthalten. Zur Kompilierzeit ist alles bekannt. Das heißt, ich möchte hier so etwas haben:Statische Initialisierung einer Struktur mit Arrays unterschiedlicher Länge

ID1 => name: someString 
     flagCount: 3 
     flags: [1, 5, 10] 

statisch erstellt (wenn möglich). Natürlich ist eine Erklärung wie:

struct Info 
{ 
    const char* name; 
    int flagCount; 
    int flags[]; 
}; 

würde so lange ideal, wie ich es wie ...

initialisieren konnte
Info infos [] = { ... }; 

was nicht möglich ist, aufgrund der Arrays unterschiedlicher Länge (außer I Ich vermisse etwas. Alternativ habe ich über (ab) boost::assign dafür verwendet, aber ich frage mich, ob es eine empfohlene Lösung dafür gibt. Mir geht es gut, wenn ich nur die Info-Strukturen in einem Array speichern kann und an anderer Stelle.

Bearbeiten: Ein Hinweis auf die aktuelle Lösung. Im Moment habe ich:

struct Info 
{ 
    Info (const std::vector<int>& flags) : flags {} 
    std::vector<int> flags; 
}; 

und ich verwende: (Template-basierte)

const std::map<ID, Info> map = boost::assign::map_list_of 
    ("ID1", Info (boost::assign::list_of (1)(2)(3)); 

das funktioniert, ich bin nur neugierig, ob es eine einfachere Lösung.

+0

Kennen Sie die Länge der Flags-Array für jedes Info-Objekt im Array zur Kompilierzeit? – dirkgently

+0

Ja. Für verschiedene Infos ist es jedoch anders. – Anteru

Antwort

1

Die Elemente in einem Array müssen die gleiche Größe haben, sonst können Sie nicht auf infos[i] zugreifen - der Compiler müsste durch das Array gehen und die Größe jedes Elements bis zu i überprüfen Finde, wo der nächste angefangen hat. Sie können genügend Speicher für jedes Element zusammenhängend zuweisen und dann ein Array von Zeigern zu den Elementen erstellen (Zeiger haben eine feste Größe). Wenn Sie nur das Mapping benötigen und die Infos nicht indexieren, wird Ihre Map als Zeiger-ID angezeigt.

Alternativ können Sie das Array Info::flags groß genug für die maximalen Flags machen, oder, wie Sie wissen, die Größe zur Kompilierzeit, wenn es nur einige Flags gibt, oder es zu einem Array von Flags machen, so dass Info ein ist Struktur mit fester Größe

+0

Hört sich vernünftig an, obwohl ich ziemlich sicher bin, dass ich zur Kompilierzeit ein "Array" mit verschiedenen Längenelementen erstellen kann, indem ich etwas wie boost :: mpl :: vector verwende und die Informationen in die Typen selbst verschiebe. – Anteru

1

Entweder verwenden, um einen Zeiger auf den Variable-Länge-Array:

struct Info 
{ 
    const char* name; 
    int flagCount; 
    int *flags; 
}; 

oder feste Größe Array groß genug, um alle Flags zu halten:

struct Info 
{ 
    const char* name; 
    int flagCount; 
    int flags[MAX_FLAGS]; 
}; 

Beiden Lösungen etwas Speicher verschwenden; aber für Lösung 1 ist es nur ein Zeiger pro Struktur; Beachten Sie, dass Sie diese Lösung bereits implizit für das Namensfeld verwenden.

1

Die Verwendung eines Vektors, wie Sie es getan haben, ist mit ziemlicher Sicherheit die beste Lösung. oefe hat Ihnen eine Lösung gegeben, bei der Sie eine gewisse Indirektion in die Info's selbst einbeziehen, eine andere Option ist indirekt in der Map, d. h. map<ID, Info*> (oder seit Sie boost map<ID, shared_ptr<Info> > verwenden) und definieren Info wie. Mach das eigentlich nicht. Verwende einen Vektor. Es ist die beste Lösung.

struct Info { 
    const char *name; 
    int flagCount; 
    int flags[1]; // this is cheating... 
}; 

Info* make_info(int count) { 
     char *buf = new char[sizeof(Info) + (sizeof(int) * (count - 1))]; 
     Info *rv = static_cast<Info*>(static_cast<void*>(buf)); 
     rv->flagCount = count; 
} 
Verwandte Themen