#ifndef __TEST__
#define __TEST__
namespace std
{
template<typename T>
class list;
}
template<typename T>
void Pop(std::list<T> * l)
{
while(!l->empty())
l->pop();
}
#endif
und benutzte diese Funktion in meinem Haupt. Ich bekomme Fehler. Natürlich weiß ich, dass es mehr Vorlagenparameter für std::list
( Allokator, denke ich) gibt. Aber das ist nebensächlich. Muss ich die vollständige Vorlagendeklaration einer Vorlagenklasse kennen, um sie weiterleiten zu können?
EDIT: Ich habe vorher keinen Zeiger benutzt - es war eine Referenz. Ich werde es mit dem Zeiger ausprobieren.
std::allocator<T>
__TEST__
ist eine reservierte Kennung, verwenden Sie sie nicht .Antworten:
Das Problem ist nicht, dass Sie eine Vorlagenklasse nicht vorwärts deklarieren können. Ja, Sie müssen alle Vorlagenparameter und ihre Standardeinstellungen kennen , um sie korrekt weiterleiten zu können:
Aber um auch eine solche voraus Erklärung
namespace std
wird ausdrücklich von der Norm verboten: Die einzige Sache , die Sie erlaubt sind zu setzen instd
eine Vorlage Spezialisierung , die gemeinhinstd::less
auf einem benutzerdefinierten Typ. Jemand anderes kann bei Bedarf den entsprechenden Text zitieren.Gerade
#include <list>
und machen sich keine Sorgen darüber.Übrigens ist jeder Name, der doppelte Unterstriche enthält, für die Verwendung durch die Implementierung reserviert. Sie sollten also so etwas wie
TEST_H
anstelle von verwenden__TEST__
. Es wird keine Warnung oder ein Fehler generiert, aber wenn Ihr Programm mit einer implementierungsdefinierten Kennung kollidiert, kann nicht garantiert werden, dass es korrekt kompiliert oder ausgeführt wird: Es ist fehlerhaft . Ebenfalls verboten sind Namen, die unter anderem mit einem Unterstrich gefolgt von einem Großbuchstaben beginnen. Beginnen Sie Dinge im Allgemeinen nicht mit Unterstrichen, es sei denn, Sie wissen, mit welcher Magie Sie es zu tun haben.quelle
namespace std
Übrigen weiterzuleiten?#pragma once
lieber die # ifdefs verwenden? Es wird heutzutage von den meisten Compilern unterstützt.#pragma
, deshalb. Obwohl es eine Option ist.Ich habe das Problem gelöst.
Ich habe eine OSI-Ebene (Schieberegler, Ebene 2) für eine Netzwerksimulation in C ++ (Eclipse Juno) implementiert. Ich hatte Frames (Vorlage
<class T>
) und ihre Zustände (Zustandsmuster, Vorwärtsdeklaration).Die Lösung lautet wie folgt:
In die
*.cpp
Datei müssen Sie die Header-Datei aufnehmen, die Sie weiterleiten, d. H.Sein cpp:
Und ... eine andere Klasse.
quelle
using namespace
Dateien in eine Header-Datei ist eine sehr schlechte Vorgehensweise, da dadurch verhindert wird, dass Personen, die diese Header-Datei verwenden, lokale Namen verwenden können, die ansonsten gültig wären. Es besiegt im Grunde den gesamten Punkt der Namespaces.Für die Weiterleitungsdeklaration sollte eine vollständige Liste der Vorlagenargumente angegeben sein.
quelle
Es gibt eine begrenzte Alternative, die Sie verwenden können
Header:
cpp:
nicht in realen Programmen getestet, also erwarten Sie, dass es nicht perfekt ist.
quelle