typedef und unvollständiger Typ

8

Kürzlich habe ich viele Probleme mit typedef und unvollständigen Typ, wenn ich bestimmte Container, Allokatoren in meinem Code geändert habe.

Was ich vorher hatte

%Vor%

Obwohl nicht ganz sicher, ob die obigen Zeilen legal sind, aber das hat bei jeder Implementierung funktioniert, die ich verwendet habe. Als ich dachte, dass ich den Job mit std::tr1::array machen kann, änderte ich die obigen zwei Zeilen mit

%Vor%

Hier bricht alles zusammen, da der Compiler versucht, array zu instanziieren und fehlschlägt, da foo unvollständiger Typ ist. Alles, was ich brauchte, ist ein Verweis auf foo , und wenig Interesse an 'anderen Teilen' des Arrays. foo wird definitiv vollständig verfügbar sein, wenn ich ein solches Array erstelle.

Das gleiche Problem tritt auf, wenn typedef std::allocator<foo>::pointer foo_ptr durch typedef stack_alloc<foo,10>::pointer foo_ptr ersetzt wurde. wo eine stack_alloc Implementierung ist wie

%Vor%

Angenommen, value_type , pointer , reference , iterator usw. hängen nicht von der Vollständigkeit von T ab, und wissen, dass die Klasse nicht ohne vollständigen Typ instanziiert werden kann, wie dies typedef kann in generischer Weise unabhängig von einem bestimmten Container oder Allokator gemacht werden?

HINWEIS:

  • Nur der Vollständigkeit halber verwende ich im "echten" Code einen kleinen lokalen Speicher mit vector , anstatt ihn durch std::array zu ersetzen, obwohl das Problem gleich bleibt.
  • stack_alloc code ist bei weitem nicht vollständig und zeigt nur den Teil des Problems an.
  • Ich weiß, dass Array, sizeof usw. vollständigen Typ benötigt. Aber ich erstelle kein Objekt vom Typ all_foos mit unvollständigem foo .
  • Meine Behauptung besagt, dass Zeiger, Referenz usw. nicht von der Vollständigkeit eines Typs abhängen sollten. Ansonsten kann Konstrukt wie struct foo{ foo_ptr p;}; nicht definiert werden. Obwohl foo_ref möglicherweise nicht anders als foo& , aber foo_ptr sein kann. Überraschenderweise hat die GCC-Implementierung keinen verschachtelten Zeigertyp für tr1::array .
  • Kenne hauptsächlich, was nicht getan werden kann, und interessiert, was in dieser Situation getan werden kann. Also ein gutes Design als Lösung erwarten.
abir 19.06.2010, 08:15
quelle

2 Antworten

7

Ein Typ muss vollständig sein, damit er in einem Standardcontainer verwendet werden kann, oder das Verhalten ist nicht definiert (§17 .4.3.6 / 2). Also ist die einzige Standardlösung, das typedef nicht zu machen, bis die Klasse definiert ist.

Ich verstehe nicht, wofür der Zwischenbehälter ist:

%Vor%

In jedem Fall müssen Sie zuerst den vollständigen Typ definieren. Um ein typedef in einer Klasse zu definieren, muss diese Klasse muss instanziiert werden, was bedeutet, dass die gesamte -Datei T wie gewünscht verwenden kann.

Beispiel: stack_alloc muss T einen vollständigen Typ haben (damit sizeof(T) funktioniert), andernfalls kann die Klasse nicht instanziiert werden. Wenn die Klasse nicht instanziiert werden kann, kann die typedef nicht abgerufen werden. Ergo, Sie werden niemals die typedef davon erhalten, wenn T unvollständig ist.

    
GManNickG 19.06.2010, 09:09
quelle
2

Der Compiler kennt die Größe des unvollständigen Typs nicht, deshalb kann er ihn nicht instanziieren und ihm auch keinen Speicher zuweisen. Wenn Sie einen Zeiger auf das Objekt (wie typedef std::tr1::array<foo*, 5> all_foos; ) anstelle der Instanz des Objekts selbst haben, wird dieses Problem gelöst.

    
Dark 19.06.2010 09:19
quelle

Tags und Links