Wie kann ich einen Namespace "unbenutzen"?

85

Eine der Unklarheiten meines Entwicklungssystems (Codegear C ++ Builder) ist, dass einige der automatisch generierten Header darauf bestehen, ...

using namespace xyzzy

... Anweisungen in ihnen, die sich auf meinen Code auswirken, wenn ich ihn am wenigsten will oder erwarte.

Gibt es eine Möglichkeit, eine vorherige "using" -Anweisung irgendwie abzubrechen / zu überschreiben, um dies zu vermeiden?

Vielleicht...

unusing namespace xyzzy;
Roddy
quelle
3
Sie sollten wahrscheinlich einen Fehlerbericht mit ihrem QC-System öffnen
Kris Kumler
2
Übrigens, welche automatisch generierten Header sind das?
Kris Kumler
1
Eines Tages wird C ++ Module haben, und das Einfügen von Code in anderen Code wird bessere Kapselungskonstrukte haben. Bis dahin gibt es keinen einfachen Weg, dies zu umgehen. Erwägen Sie, Ihren eigenen Code in einen Namespace einzufügen und auf diese Weise darauf zu verweisen.
Trevor Hickey

Antworten:

57

Nee. Es gibt jedoch eine mögliche Lösung: Wenn Sie Ihre Include-Direktive in einen eigenen Namespace wie diesen einfügen ...

namespace codegear {
    #include "codegear_header.h"
} // namespace codegear

... dann werden die Auswirkungen der Verwendung von Anweisungen in diesem Header neutralisiert.

Das kann in einigen Fällen problematisch sein. Aus diesem Grund wird in jedem C ++ - Styleguide dringend empfohlen, keine "using namespace" -Anweisung in eine Header-Datei einzufügen.

Head Geek
quelle
1
Im Allgemeinen ist dies eine schreckliche Idee. C ++ - Header sollen nicht in einen alternativen Namespace aufgenommen werden, wie er hier verwendet wurde.
Aaron
23
Es ist eine schreckliche Idee, eine using-Direktive auch in eine Header-Datei aufzunehmen. Dies mildert einfach dieses Problem.
Head Geek
4
Das Platzieren des Headers in Ihrem eigenen Namespace ist keine Lösung, da dadurch die Bedeutung der Deklarationen in dieser Bibliothek geändert wird. (-1)
Richard Corden
4
Das hängt ganz davon ab, was im Header deklariert wird.
Head Geek
1
Genau deshalb ist es undefiniertes Verhalten.
Kris Kumler
56

Nein, Sie können einen Namespace nicht deaktivieren . Das einzige, was Sie tun können, ist, die using namespaceAnweisung in einen Block zu setzen, um den Umfang einzuschränken.

Beispiel:

{
    using namespace xyzzy;

} // stop using namespace xyzzy here

Möglicherweise können Sie die Vorlage ändern, die für Ihre automatisch generierten Header verwendet wird.

jk.
quelle
Können Sie ein Include in einen solchen Block einbinden?
Eclipse
Ja, das geht nicht mit automatisch generiertem Code. Kann er die Vorlage für den automatisch generierten Code ändern?
jk.
Ja, das geht nicht wirklich auf das Problem ein, das er mit Headern hat, die Namespaces verwenden.
Kip
Leider stimmt das nicht. Versuchen Sie dies:
Adam
Namespace xyzzy {const int i {using Namespace xyzzy; } // hör auf, den Namespace xyzzy hier zu benutzen
Adam
17

Bei Konflikten können explizite Namespaces verwendet werden:

string x; // Doesn't work due to conflicting declarations
::string y; // use the class from the global namespace
std::string z; // use the string class from the std namespace
Finsternis
quelle
10

Zum späteren Nachschlagen: Seit der XE-Version gibt es einen neuen Wert, den Sie using namespace System;# definieren können, um das gefürchtete int zu vermeiden : DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE

cdelacroix
quelle
Dies scheint jedoch nicht richtig zu funktionieren. Zumindest in allen Fällen habe ich es versucht (mit BCB6). Ich habe dann auf das Hinzufügen expliziter Namespaces zu Konflikten zurückgegriffen und - noch schlimmer - einen Header eingefügt, um Konflikte mit Typnamen zu vermeiden ...
Wolf
6

Wie wäre es mit sed, perl oder einem anderen Befehlszeilentool als Teil Ihres Erstellungsprozesses, um die generierten Header zu ändern, nachdem sie generiert wurden, aber bevor sie verwendet werden?


quelle
1

Ein kurzes Experiment mit Visual Studio 2005 zeigt, dass Sie diese Header in Ihren eigenen benannten Namespace einschließen können und dann das, usewas Sie von diesem Namespace benötigen (aber nicht useden gesamten Namespace, da dadurch der Namespace eingeführt wird, den Sie ausblenden möchten.

Kasprzol
quelle
1
Dies führt wahrscheinlich zu Problemen bei der Namensverfälschung, wenn die Header-Dateien Deklarationen für eine Bibliothek sind. Die Kompilierung ist erfolgreich, aber der Linker kann die Definitionen nicht finden, da sie bereits in einem anderen Namespace kompiliert worden wären.
Eclipse
-1
#include<iostream>
#include<stdio.h>
namespace namespace1 {
    int t = 10;
}
namespace namespace2 {
    int t = 20;
}
int main() {
using namespace namespace1;
    printf("%d" , t);
    printf("%d" , namespace2::t);
}
Narendra Kumawat
quelle
1
Bitte erläutern Sie Ihre Antwort!
Mazz
Sie können Scope Resolution Operator verwenden, um eine andere Namespace-Variable zu verwenden
Narendra Kumawat
3
Behandelt die Frage nicht
MM