7 Stimmen

"using typedef-name ... as class" bei einer Forward-Deklaration

Ich mache hier einige richtlinienbasierte Entwürfe, und ich muss viele Vorlagentypen typisieren, um die Namen zu verkürzen.
Jetzt kommt das Problem, dass wenn ich einen Zeiger auf einen dieser Typen verwenden muss, ich versuche, ihn einfach weiterzudeklarieren, aber der Compiler beschwert sich mit einer test.cpp:8: error: using typedef-name ‘Test1’ after ‘class’
Es hat nichts mit der Größe zu tun, da ich das Objekt überhaupt nicht benötige, sondern nur einen Zeiger in einer ".h"-Datei, in die ich nicht die gesamte Vorlage einfügen möchte.
Dies ist g++:

//Works
class Test{};
class Test;

//Doesn't work
class Test{};
typedef Test Test1;
class Test1;

Haben Sie einen Tipp?

17voto

Johannes Schaub - litb Punkte 479831

Das ist richtig. Ein Typedef-Name kann in einer solchen Forward-Deklaration nicht verwendet werden (dies wird technisch als elaborierter Typenspezifizierer bezeichnet, und wenn ein solcher Spezifizierer in einen Typedef-Namen aufgelöst wird, ist das Programm schlecht geformt).

Ich verstehe nicht, warum Sie eigentlich brauchen die Vorwärtsmeldung überhaupt erst zu erstellen. Denn wenn der Typedef bereits vorhanden ist, warum nicht einfach diesen Typedef verwenden? Es ist genauso gut, diese Klasse zu bezeichnen.

bearbeiten : Aus Ihrem Kommentar geht hervor, dass Sie einen Kopf für die Vorwärtsdeklaration benötigen, ähnlich wie bei der <iosfwd> . Wenn Ihre Vorlage also heißt Test_Template_Name_Long kann eine Kopfzeile wie folgt aussehen

TestFwd.h

template<typename A, typename B> 
class Test_Template_Name_Long;

typedef Test_Template_Name_Long<int, bool> Test1;

Dann können Sie einfach diese Kopfzeile verwenden, anstatt die class Test1 , von der der Compiler keine Ahnung hat, was sie ist (und sie für eine neue Klasse hält, unabhängig von allen Vorlagen und Typdefs).

0 Stimmen

Ich habe versucht, dich hochzuvoten, weil du mich geschlagen hast, aber ich habe keine Stimmen mehr für heute :(

2 Stimmen

Nun, das Problem kommt in einer .cpp-Datei, die diese seconday .h-Datei und die ursprüngliche mit dem typedef enthält. Ich brauche die Vorwärtsdeklaration, weil ich einen Zeiger auf diese Klasse deklarieren muss und vermeiden möchte, die Vorlagendatei (mit dem Typedef darin) einzuschließen. Es gibt also keine Lösung für eine solche Sache?

0 Stimmen

Dann müssen Sie die Klasse und das Typedef in der Datei explizit weiterdeklarieren. Denken Sie daran, dass zwischen Dateien typisierte Namen nicht existieren - der Compiler expandiert sie zur Kompilierzeit in ihre untypisierten Namen. Wenn Sie den typisierten Namen später einfach weiterdeklarieren, wird dies zur Link-Zeit fehlschlagen, da nach der Kompilierung kein solcher Name mehr existieren sollte.

2voto

Billy ONeal Punkte 100691
typedef Test Test1;
class Test1;

scheitert, weil die typedef Anweisung dient als Deklaration für den Typ Test1.

Wenn der Compiler den Typedef sieht, merkt er sich im Grunde, dass Test1 ein Synonym für Test ist. Wenn er dann sieht class Test1; denkt es, dass es einen neuen Typ gibt, den Sie deklarieren. Aber es kann das nicht als Deklaration behandeln, weil der Name Test1 bereits von der Typedef verwendet wird.

Wenn Sie z.B. eine Forward-Deklaration für Test1 verwenden wollen, müssen Sie den Typedef in jede Datei einfügen, die diesen Typedef als Forward-Deklaration verwendet. Daher müssen Sie anstelle von class Test1; Sie tun würden:

class Test;
typedef Test Test1;

2voto

Ahmed Nassar Punkte 4493

Ein weiterer Fall, in dem diese Situation auftritt, ist dieser:

// File: network_fwd.hpp
#ifndef __NETWORK_FWD_HPP__
#define __NETWORK_FWD_HPP__
class Network;
typedef Network GarnetNetwork;
#endif // __NETWORK_FWD_HPP__

// File: network.hpp
#include "network_fwd.hpp"

class GarnetIntLink : public BasicLink
{
  public:

    friend class GarnetNetwork;

};

Ich musste das tun, weil es tatsächlich eine Klasse namens GarnetNetwork gab, die ich in die Klasse Network zusammengeführt habe, und ich wollte das im gesamten Rest des Codes unter Verwendung dieses Typedefs propagieren. GCC gibt immer noch diese Meldung aus: Fehler: Verwendung des Typedef-Namens 'GarnetNetwork' nach 'Klasse' .

Ich bin Ihnen wirklich dankbar für Ihre Hilfe in diesem Fall.

NB: Übrigens habe ich diese Frage hier gepostet, weil ich dachte, dass es so ziemlich dasselbe ist, und um die Gemeinschaft nicht abzulenken.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X