Namespace deklariert in file a, Nutzung in file b
-
Hallo zusammen,
ich hab eine Frage dazu, wie ich namespaces benutz:
In der Datei a.h hab ich den Namespace Clamping deklariert:
namespace Clamping { /* * Possible Clamping Methods */ enum Method { SCL_NEAREST, /**<If this method is chosen, the value of the element next to the undefined is taken*/ SCL_NEUTRAL /**<If this method is chosen, a neutral element has to be defined by the user. This is taken for the undefined elements*/ }; } // namespace clampingIn der Datei b.h will ich auf diesen Namespace zugreifen, um der Klasse b eine Membervariable vom Typ Clamping::Method zu geben. Wenn ich in der Klasse b einfach
Clamping::Method clamping;angeb, dann sagt mir der compiler (g++):
b.h:201: error: ‘Clamping’ has not been declared b.h:201: error: ISO C++ forbids declaration of ‘Method’ with no type b.h:201: error: expected ‘;’ before ‘clamping’Ich hab beim Recherchieren festgestellt, dass ich in Klasse b
#include "a.h"einfügen könnte. Das ist aber leider keine Option, da ich an einer größeren Bibliothek arbeite, wo ich dann die einzelnen Abhängigkeiten verletze. Auch
using namespace Clampinghat bisher keinen Erfolg gebracht...
Trotzdem möchte/muss ich von b aus den namespace Clamping aus a erreichen (in b wird bspw. auch ein anderer namespace deklariert, den man problemlos von a aus erreichen kann...). Welche Möglichkeiten gibt es da noch?
Es wäre super, wenn mir einer von euch helfen könnte!
Danke im Voraus,
centershock
-
Wie, du verletzt die Abhängigkeiten?
Wenn Header b etwas aus Header a benötigt, was definitiv der Fall ist, musst Du in b eben auch a inkludieren. Da führt kein Weg dran vorbei
Wenn Du in dieser Bibliothek arbeitest/arbeiten darfst, musst Du doch auch das Recht haben, evtl. neue Abhängigkeiten hinzuzufügen. Das willst Du doch sogar, weil Du ja eben was aus a nutzen willst...
-
Naja, vielleicht verletze ich da keine Abhängigkeiten, aber das Inkludieren von a in b verursacht sehr hohen Aufwand, um wieder alles funktionstüchtig zu machen...
Ist das Inkludieren von a in b tatsächlich die einzige Möglichkeit?
-
centershock schrieb:
das Inkludieren von a in b verursacht sehr hohen Aufwand, um wieder alles funktionstüchtig zu machen...
Wieso denn das?
centershock schrieb:
Ist das Inkludieren von a in b tatsächlich die einzige Möglichkeit?
Ja.
-
EOutOfResources schrieb:
centershock schrieb:
das Inkludieren von a in b verursacht sehr hohen Aufwand, um wieder alles funktionstüchtig zu machen...
Wieso denn das?
centershock schrieb:
Trotzdem möchte/muss ich von b aus den namespace Clamping aus a erreichen (in b wird bspw. auch ein anderer namespace deklariert, den man problemlos von a aus erreichen kann...).
Schaut nach zyklischen Abhängigkeiten aus...
-
Du könntest Mal beschreiben, was in a genau definiert wird und was in b. Einfache Lösung wäre die Definition dieser Struktur auszulagern in eine Datei c, die von a und b inkludiert wird.
Vielleicht ist auch ein Redesign gut, aber Du möchtest wohl so wenig wie möglich verändern.
-
Du könntest Mal beschreiben, was in a genau definiert wird und was in b.
Mir ist nicht ganz klar, was du da genau meinst. Ich versuche aber mal zu beschreiben was ich da versteh.
Bei Klasse a handelt es sich um ein algorithmisches Skelett, welches den Datentyp, der in Klasse b definiert wird, benutzt.
In a ist es wie folgt:
template<typename T> class b; template<typename Tin, typename Tout = Tin> class a; /** * @brief In this namespace possible clamping methods are defined */ namespace Clamping { /* * Possible Clamping Methods */ enum Method { SCL_NEAREST, /**<If this method is chosen, the value of the element next to the undefined is taken*/ SCL_NEUTRAL /**<If this method is chosen, a neutral element has to be defined by the user. This is taken for the undefined elements*/ }; } // namespace clampingIn Klasse b sieht es wie folgt aus:
template<typename Tin, typename Tout> class a; /** * @brief In this namespace are the possible distributions for the Vector class defined. */ namespace Distribution { /** * Enumeration of the possible distributions for a vector. */ enum Type { none, /**< This distribution is set during the initialization of a vector. It can not be set as a distribution with the Vector::setDistribution(Distribution::Type, cl_uint) function. */ single, /**< If a vector is set to this distribution, the data of the vector is stored on a single device. */ striped, /**< If a vector is set to this distribution, the data of the vector is striped over multiple devices. Therefore, the data is split up and a chunk is stored every device. */ mirrored, /**< If a vector is set to this distribution, the complete data is copied to every device. */ overlap }; }Desweiteren gibt es noch eine weitere .h-Datei, die als Ausgangspunkt für die Benutzung der Bibliothek dient.
Hier werden die beiden einzelnen Klassen inkludiert:
#include "b.h" #include "a.h"Ich denke, das Problem ist, dass b vor a inkludiert wird. Wenn ich nun daher in b a inkludiere, komme ich ja zu der zyklischen Abhängigkeit.
Den Namespace Distribution aus der Klasse b kann ich problemlos in der Klasse a benutzen. Nur halt den Namespace Clamping aus a nicht in b.
Klasse a und b inkludieren nichts von der Bibliothek, das sollte meiner Meinung nach über die Klasse, die als Ausgangspunkt dient, geschehen.
Ich hoffe, das ist das wonach du gefragt hast, und es ist verständlich...
-
Na ja, Du hast nicht viel Neues erzählt und die Codes enthalten nur Forward-Deklarationen und enums.
Ich frag Mal anders: Was sind die in a und b definierten Typen? In a ist ein algorithmisches Skelett, okay. Und was ist b? Macht es Sinn, dass b a kennt? Wieso ist dieses enum in a definiert, gehört es zwangsläufig zu a? Oder wird es bisher nur ausschließlich von a verwendet (aber jetzt auch von b)?
-
b ist ein dem std::vector ähnlicher Datentyp. Das Skelett in a benutzt diesen Datentyp, daher muss a b kennen.
Bisher war es nicht so, dass der Datentyp b das Skelett a kennen musste.
Das enum ist in a definiert, weil es zu a gehört. In dem enum wird festgelegt, wie mit Randzugriffen umgegangen wird. Da für diese Randzugriffe ein extra Array angelegt wurde, hatte der Datentyp damit bisher nichts zu tun. Jetzt soll dieses extra Array aber in den Datentyp "mit rein".
-
[quote="centershock"]
Hier werden die beiden einzelnen Klassen inkludiert:
#include "b.h" #include "a.h"Ich denke, das Problem ist, dass b vor a inkludiert wird. Wenn ich nun daher in b a inkludiere, komme ich ja zu der zyklischen Abhängigkeit.
wieso?
es sieht im letztendlichen file doch so aus:
// #include "b.h" wird zu // #include "a.h" wird zu // definitionen von a // definitionen von b // #include "a.h" wird zu //definitionen von a, aber nicht merh genutzt wegen include guardsdu inkludierst so doch nur a quasi 2mal, aber da du auf jedenfall includeguards verwenden solltest, hast du kein roblem mit multipler definition...
-
Ok, auf dem Genauigkeitsgrad kommen wir nicht weiter, glaub ich...
Macht aber nichts. Was hältst Du davon, das enum in eine dritte Datei c auszulagern und diese ausgehend von a und b zu initialisieren? Da b ja a nicht braucht, sondern nur das enum wäre die zirkuläre Abhängigkeit damit ja perdu.
-
Ok, ich hab den namespace Clamping in eine weitere Datei ausgelagert und diese dann in a und b inkludiert.
Jetzt bekomme ich den Fehler in Klasse b:
error: previous definition of ‘class b’Wo kommt das denn jetzt her?
-
Wenn b a nicht braucht, wieso steht in b.h dann:
template<typename Tin, typename Tout> class a;?
-
centershock schrieb:
Ok, ich hab den namespace Clamping in eine weitere Datei ausgelagert und diese dann in a und b inkludiert.
Jetzt bekomme ich den Fehler in Klasse b:
error: previous definition of ‘class b’Wo kommt das denn jetzt her?
Include-Guards gesetzt?
-
EOutOfResources schrieb:
centershock schrieb:
Ok, ich hab den namespace Clamping in eine weitere Datei ausgelagert und diese dann in a und b inkludiert.
Jetzt bekomme ich den Fehler in Klasse b:
error: previous definition of ‘class b’Wo kommt das denn jetzt her?
Include-Guards gesetzt?
oder wenigstens
#pragma once
-
Skym0sh0 schrieb:
oder wenigstens
#pragma onceLeider nicht Standard. Ich hoffe, sie werden es irgendwann einmal standardisieren.
-
ja, dass es nicht standard ist weiss ich...
mh, ich weiss nicht wieso, aber ich mag pragma once nicht. die normalen include guards per #ifndef und #define sind mir viel lieber...
wobei eigentlich ist so wie in java schöner, aber alles rein subjektive empfindung...
-
Gott sei Dank, es funktioniert endlich!!!
Ich hab die Datei, in die ich den Clamping-namespace ausgelagert hab, nur in class b inkludiert und die Include-Guards gesetzt. Dann hat es funktioniert.
Ich danke euch *vielmals* für eure Hilfe!!
Gruß,
centershock
-
a nutzt das aber auch. Klar nutzt b auch c und daher ist das Inkludieren von b in a für den Moment ausreichend, aber c in a und in b zu inkludieren, sollte nicht zu einem Fehler führen und ist eigentlich auch die sauberere Lösung.
-
Du hast recht, es in beiden Klassen zu inkludieren ist besser.
Hab ich jetzt auch gemacht und führt auch nicht zu einem Fehler!
-
centershock schrieb:
Hab ich jetzt auch gemacht und führt auch nicht zu einem Fehler!
Demzufolge hattest du die Include-Guards vergessen, nicht?
EDIT: Zeitform gefixt