Gibt es eine bessere Möglichkeit, verschachtelte Namespaces in C ++ innerhalb des Headers auszudrücken?


97

Ich bin von C ++ zu Java und C # gewechselt und denke, dass die Verwendung von Namespaces / Paketen dort viel besser ist (gut strukturiert). Dann bin ich zu C ++ zurückgekehrt und habe versucht, Namespaces auf die gleiche Weise zu verwenden, aber die erforderliche Syntax in der Header-Datei ist schrecklich.

namespace MyCompany
{
    namespace MyModule
    {
        namespace MyModulePart //e.g. Input
        {
            namespace MySubModulePart
            {
                namespace ...
                {
                    public class MyClass    

Folgendes erscheint mir ebenfalls seltsam (um den tiefen Einzug zu vermeiden):

namespace MyCompany
{
namespace MyModule
{
namespace MyModulePart //e.g. Input
{
namespace MySubModulePart
{
namespace ...
{
     public class MyClass
     {

Gibt es eine kürzere Möglichkeit, das oben Gesagte auszudrücken? Mir fehlt so etwas

namespace MyCompany::MyModule::MyModulePart::...
{
   public class MyClass

Aktualisieren

Ok, einige sagen, dass das Konzept der Verwendung in Java / C # und C ++ unterschiedlich ist. "Ja wirklich?" Ich denke, dass das (dynamische) Laden von Klassen nicht der einzige Zweck für Namespaces ist (dies ist eine sehr technisch begründete Perspektive). Warum sollte ich es nicht für eine Lesbarkeit und Strukturierung verwenden, z. B. an "IntelliSense" denken?

Derzeit gibt es keine Logik / Kleber zwischen einem Namespace und dem, was Sie dort finden können. Java und C # machen das viel besser ... Warum <iostream>Namespace einschließen und haben std? Ok, wenn Sie sagen, die Logik sollte sich auf den einzuschließenden Header stützen, warum verwendet das #include keine "IntelliSense" -freundliche Syntax wie #include <std::io::stream>oder <std/io/stream>? Ich denke, die fehlende Strukturierung in den Standardbibliotheken ist eine Schwäche von C ++ im Vergleich zu Java / C #.

Wenn die Eindeutigkeit für eifrige Konflikte ein Punkt ist (was auch ein Punkt von C # und Java ist), ist es eine gute Idee, den Projekt- oder Firmennamen als Namespace zu verwenden, finden Sie das nicht?

Einerseits heißt es, C ++ sei am flexibelsten ... aber alle sagten "mach das nicht"? Es scheint mir, dass C ++ viele Dinge kann, aber eine schreckliche Syntax hat, selbst für die einfachsten Dinge in vielen Fällen im Vergleich zu C #.

Update 2

Die meisten Benutzer sagen, es sei Unsinn, eine tiefere Verschachtelung als zwei Ebenen zu erstellen. Ok, was ist mit Windows :: UI :: Xaml und Windows :: UI :: Xaml :: Controls :: Primitives-Namespaces in der Win8-Entwicklung? Ich denke, die Verwendung von Namespaces durch Microsoft ist sinnvoll und in der Tat tiefer als nur 2 Ebenen. Ich denke, größere Bibliotheken / Projekte benötigen eine tiefere Verschachtelung (ich hasse Klassennamen wie ExtraLongClassNameBecauseEveryThingIsInTheSameNameSpace ... dann könnten Sie auch alles in den globalen Namespace einfügen.)

Update 3 - Fazit

Die meisten sagen "Tu es nicht", aber ... selbst Boost hat eine tiefere Verschachtelung als ein oder zwei Level. Ja, es ist eine Bibliothek, aber: Wenn Sie wiederverwendbaren Code möchten, behandeln Sie Ihren eigenen Code wie eine Bibliothek, die Sie jemand anderem geben würden. Ich verwende auch eine tiefere Verschachtelung für Erkennungszwecke unter Verwendung von Namespaces.


3
Ist es ein Missbrauch von namespaceSchlüsselwörtern?
Nawaz

4
Namespaces und C # / Java-Modulsysteme dienen nicht demselben Zweck. Daher sollten Sie nicht versuchen, sie auf dieselbe Weise zu verwenden. und nein, es gibt keine einfachere Syntax, nur weil es keinen Sinn macht, eine Syntax bereitzustellen, um Dinge einfacher zu machen, die nicht dazu gedacht sind.
PlasmaHH

@PlasmaHH ... also ist die Schwäche die fehlende Strukturierung der Standardbibliothek von C ++? (siehe mein einfaches Beispiel im Update)
Beachwalker

@Stegi: Wenn Sie fundierte Argumente dafür liefern können, warum es fehlt und welche soliden Vorteile eine solche Strukturierung hätte, könnten wir über mögliche Schwächen sprechen. Bis dahin würde ich javas endloses Verschachteln von Paketen bestenfalls verwirrend nennen.
PlasmaHH

3
@PlasmaHH Intellisense und andere Helfer für / nach der Aufnahme von Headern (Paketen). Große Projekte innerhalb eines Unternehmens benötigen möglicherweise mehr als eine Verschachtelung (z. B. vw :: golflib :: io), um eindeutig zu bestimmen, was ein Namespace in welchem ​​"Bereich" enthält. Nun, Sie könnten einfach vw :: verwenden, aber wenn der Namespace verwendet werden soll, um Konflikte zu vermeiden, warum sind die so schrecklich zu deklarieren? Dies führt zu einem Punkt, an dem niemand es verwendet oder nur einen Namespace mit einer Tiefe von eins verwendet (wie oft vorgeschlagen).
Beachwalker

Antworten:


130

C ++ 17 könnte die Definition verschachtelter Namespaces vereinfachen:

namespace A::B::C {
}

ist äquivalent zu

namespace A { namespace B { namespace C {
} } }

Siehe (8) auf der Namespace-Seite unter cppreference:
http://en.cppreference.com/w/cpp/language/namespace


4
... aktiviert durch Compiler-Schalter/std:c++latest
sonniger Mond

3
Beachten Sie, dass bei Verwendung /std:c++latestvon Visual Studio 2015 und Boost möglicherweise sehr mystische Compilerfehler auftreten, wenn Sie einige Boost-Header einfügen. Ich war mit diesem Problem konfrontiert, wie in dieser StackOverflow-Frage beschrieben
Vivit

1
Es funktioniert wie es ist, Namespace A :: B :: C. Ich habe mit g ++ - 6.0
ervinbosenbacher


17

Ich unterstütze Peterchens Antwort voll und ganz , möchte aber etwas hinzufügen, das einen anderen Teil Ihrer Frage anspricht.

Das Deklarieren von Namespaces ist einer der sehr seltenen Fälle in C ++, in denen ich die Verwendung von #defines wirklich mag .

#define MY_COMPANY_BEGIN  namespace MyCompany { // begin of the MyCompany namespace
#define MY_COMPANY_END    }                     // end of the MyCompany namespace
#define MY_LIBRARY_BEGIN  namespace MyLibrary { // begin of the MyLibrary namespace
#define MY_LIBRARY_END    }                     // end of the MyLibrary namespace

Dadurch entfällt auch die Notwendigkeit von Kommentaren in der Nähe der schließenden Klammer des Namespace (Haben Sie jemals zum Ende einer großen Quelldatei gescrollt und versucht, Klammern hinzuzufügen / zu entfernen / auszugleichen, bei denen Kommentare darüber fehlten, welche Klammer welchen Bereich schließt? Kein Spaß .).

MY_COMPANY_BEGIN
MY_LIBRARY_BEGIN

class X { };

class Y { };

MY_LIBRARY_END
MY_COMPANY_END

Wenn Sie alle Namespace-Deklarationen in eine einzelne Zeile setzen möchten, können Sie dies auch mit ein wenig (ziemlich hässlicher) Präprozessor-Magie tun:

// helper macros for variadic macro overloading
#define VA_HELPER_EXPAND(_X)                    _X  // workaround for Visual Studio
#define VA_COUNT_HELPER(_1, _2, _3, _4, _5, _6, _Count, ...) _Count
#define VA_COUNT(...)                           VA_HELPER_EXPAND(VA_COUNT_HELPER(__VA_ARGS__, 6, 5, 4, 3, 2, 1))
#define VA_SELECT_CAT(_Name, _Count, ...)       VA_HELPER_EXPAND(_Name##_Count(__VA_ARGS__))
#define VA_SELECT_HELPER(_Name, _Count, ...)    VA_SELECT_CAT(_Name, _Count, __VA_ARGS__)
#define VA_SELECT(_Name, ...)                   VA_SELECT_HELPER(_Name, VA_COUNT(__VA_ARGS__), __VA_ARGS__)

// overloads for NAMESPACE_BEGIN
#define NAMESPACE_BEGIN_HELPER1(_Ns1)             namespace _Ns1 {
#define NAMESPACE_BEGIN_HELPER2(_Ns1, _Ns2)       namespace _Ns1 { NAMESPACE_BEGIN_HELPER1(_Ns2)
#define NAMESPACE_BEGIN_HELPER3(_Ns1, _Ns2, _Ns3) namespace _Ns1 { NAMESPACE_BEGIN_HELPER2(_Ns2, _Ns3)

// overloads for NAMESPACE_END
#define NAMESPACE_END_HELPER1(_Ns1)               }
#define NAMESPACE_END_HELPER2(_Ns1, _Ns2)         } NAMESPACE_END_HELPER1(_Ns2)
#define NAMESPACE_END_HELPER3(_Ns1, _Ns2, _Ns3)   } NAMESPACE_END_HELPER2(_Ns2, _Ns3)

// final macros
#define NAMESPACE_BEGIN(_Namespace, ...)    VA_SELECT(NAMESPACE_BEGIN_HELPER, _Namespace, __VA_ARGS__)
#define NAMESPACE_END(_Namespace, ...)      VA_SELECT(NAMESPACE_END_HELPER,   _Namespace, __VA_ARGS__)

Jetzt können Sie dies tun:

NAMESPACE_BEGIN(Foo, Bar, Baz)

class X { };

NAMESPACE_END(Baz, Bar, Foo) // order doesn't matter, NAMESPACE_END(a, b, c) would work equally well

Foo::Bar::Baz::X x;

Um tiefer als drei Ebenen zu verschachteln, müssten Sie Hilfsmakros bis zur gewünschten Anzahl hinzufügen.


So sehr ich #defines auch nicht mag, ich bin ziemlich beeindruckt von dieser Präprozessor-Magie ... nur wenn ich keine zusätzlichen Hilfsmakros für eine tiefere Verschachtelung hinzufügen muss ... nun, ich werde sie sowieso nicht verwenden. .
Galdin

12

C ++ - Namespaces werden verwendet, um Schnittstellen zu gruppieren, nicht um Komponenten zu teilen oder politische Spaltungen auszudrücken.

Der Standard tut alles, um die Java-ähnliche Verwendung von Namespaces zu verbieten. Namespace-Aliase bieten beispielsweise die Möglichkeit, tief verschachtelte oder lange Namespace-Namen einfach zu verwenden.

namespace a {
namespace b {
namespace c {}
}
}

namespace nsc = a::b::c;

Wäre namespace nsc {}dann aber ein Fehler, da ein Namespace nur mit seinem ursprünglichen Namespace-Namen definiert werden darf . Im Wesentlichen erleichtert der Standard dem Benutzer einer solchen Bibliothek die Arbeit, dem Implementierer jedoch die Arbeit . Dies hält die Leute davon ab, solche Dinge zu schreiben, mildert jedoch die Auswirkungen, wenn sie dies tun.

Sie sollten einen Namespace pro Schnittstelle haben, der durch eine Reihe verwandter Klassen und Funktionen definiert ist. Interne oder optionale Subschnittstellen können in verschachtelte Namespaces verschoben werden. Aber mehr als zwei Ebenen tief sollten eine sehr ernste rote Fahne sein.

Verwenden Sie Unterstriche und Bezeichnerpräfixe, wenn der ::Operator nicht benötigt wird.


16
Ok, was ist mit Windows :: UI :: Xaml und Windows :: UI :: Xaml :: Controls :: Primitives-Namespaces in der Win8-Entwicklung? Ich denke, die Verwendung von Namespaces durch Microsoft ist sinnvoll und in der Tat tiefer als nur 2 Ebenen.
Beachwalker

2
Die Verwendung von weniger als 2 Ebenen ist eine rote Fahne und die Verwendung von 3 oder 4 ist vollkommen in Ordnung. Der Versuch, eine flache Namespace-Hierarchie zu erreichen, wenn dies keinen Sinn ergibt, macht den eigentlichen Zweck von Namespaces zunichte - das Vermeiden von Namenskonflikten. Ich bin damit einverstanden, dass Sie eine Ebene für eine Schnittstelle und eine andere für Subschnittstellen und Interna haben sollten. Um dies herum benötigen Sie jedoch mindestens eine weitere Ebene für den Firmennamensraum (für kleine bis mittlere Unternehmen) oder zwei für Unternehmen und Geschäftsbereiche (für große Unternehmen). Andernfalls kollidieren Ihre Schnittstellennamensräume mit denen anderer Schnittstellen mit demselben Namen, die an anderer Stelle entwickelt wurden
Kaiserludi,

@Kaiserludi Was ist der technische Vorteil von company::divisionüber company_division?
Potatoswatter

@Potatoswatter Innerhalb von company :: anotherDivsion können Sie einfach die kürzere 'Division' verwenden. um auch innerhalb von Headern auf company :: division zu verweisen, in denen Sie die Verschmutzung von Namespaces höherer Ebene durch die Verwendung von 'using namespace' unbedingt vermeiden sollten. Außerhalb des Firmennamensraums können Sie weiterhin eine "using namespace company" durchführen. Wenn die Divisionsnamen nicht mit anderen Namespaces in Ihrem Bereich kollidieren, die Schnittstellennamen in einigen Divisionsnamespaces jedoch kollidieren, sodass Sie den Namespace company_division nicht verwenden können.
Kaiserludi

3
@Potatoswatter Der Punkt ist, dass Sie es praktisch kostenlos erhalten (company :: division ist nicht länger als company_division) und keinen zusätzlichen Namespace-Alias ​​definieren müssen, um es zu verwenden.
Kaiserludi

6

Nein, und bitte tu das nicht.

Der Zweck von Namespaces besteht hauptsächlich darin, Konflikte im globalen Namespace zu lösen.

Ein sekundärer Zweck ist die lokale Abkürzung von Symbolen; Beispielsweise kann eine komplexe UpdateUIMethode ein verwenden using namespace WndUI, um kürzere Symbole zu verwenden.

Ich bin in einem 1.3MLoc-Projekt und die einzigen Namespaces, die wir haben, sind:

  • importierte externe COM-Bibliotheken (hauptsächlich, um Header-Konflikte zwischen #importund zu isolieren #include windows.h)
  • Eine Ebene von "öffentlichen API" -Namensräumen für bestimmte Aspekte (Benutzeroberfläche, DB-Zugriff usw.)
  • Namespaces "Implementation Detail", die nicht Teil der öffentlichen API sind (anonyme Namespaces in CPPs oder ModuleDetailHereBeTygersNamespaces in Nur-Header-Bibliotheken)
  • Aufzählungen sind nach meiner Erfahrung das größte Problem. Sie verschmutzen wie verrückt.
  • Ich finde es immer noch viel zu viele Namespaces

In diesem Projekt verwenden Klassennamen usw. einen aus zwei oder drei Buchstaben bestehenden "Regions" -Code (z . B. CDBNodeanstelle von DB::CNode). Wenn Sie Letzteres bevorzugen, gibt es Platz für eine zweite Ebene von "öffentlichen" Namespaces, aber nicht mehr.

Klassenspezifische Aufzählungen usw. können Mitglieder dieser Klassen sein (obwohl ich der Meinung bin, dass dies nicht immer gut ist und es manchmal schwer zu sagen ist, ob Sie sollten)

Es wird auch selten ein "Firmen" -Namensraum benötigt, außer wenn Sie große Probleme mit Bibliotheken von Drittanbietern haben, die als Binärdateien verteilt werden, keinen eigenen Namespace bereitstellen und nicht einfach in einen eingefügt werden können (z. B. in einer Binärdatei) Verteilung). Nach meiner Erfahrung ist es jedoch viel einfacher , sie in einen Namespace zu zwingen .


[Bearbeiten] Gemäß Stegis Folgefrage:

Ok, was ist mit Windows :: UI :: Xaml und Windows :: UI :: Xaml :: Controls :: Primitives-Namespaces in der Win8-Entwicklung? Ich denke, die Verwendung von Namespaces durch Microsoft ist sinnvoll und in der Tat tiefer als nur 2 Ebenen

Es tut mir leid, wenn ich nicht klar genug war: Zwei Levels sind keine harte Grenze, und mehr ist an sich nicht schlecht. Ich wollte nur darauf hinweisen, dass Sie meiner Erfahrung nach selbst auf einer großen Codebasis selten mehr als zwei benötigen . Tiefer oder flacher nisten ist ein Kompromiss.

Nun ist der Microsoft-Fall wohl anders. Vermutlich ein viel größeres Team, und der gesamte Code ist eine Bibliothek.

Ich würde davon ausgehen , Microsoft wird hier den Erfolg der .NET - Bibliothek zu imitieren, wo Namensräume zum Beitrag Auffindbarkeit der umfangreichen Bibliothek. (.NET hat ungefähr 18000 Typen.)

Ich würde weiter annehmen, dass es in einem Namespace ein optimales Symbol (Größenordnung von Symbolen) gibt. Sagen wir, 1 macht keinen Sinn, 100 klingt richtig, 10000 ist eindeutig zu viel.


TL; DR: Es ist ein Kompromiss, und wir haben keine harten Zahlen. Gehen Sie auf Nummer sicher und übertreiben Sie in keine Richtung. Das "Tu das nicht" kommt nur von "Du hast Probleme damit, ich hätte Probleme damit, und ich sehe keinen Grund, warum du es brauchen würdest.".


7
Ok, was ist mit Windows :: UI :: Xaml und Windows :: UI :: Xaml :: Controls :: Primitives-Namespaces in der Win8-Entwicklung? Ich denke, die Verwendung von Namespaces durch Microsoft ist sinnvoll und in der Tat tiefer als nur 2 Ebenen.
Beachwalker

2
Wenn ich Konstanten mit globalem Zugriff benötige, möchte ich sie in einen Namespace mit einem Namen wie Constantseinfügen und dann verschachtelte Namespaces mit geeigneten Namen erstellen, um die Konstanten zu kategorisieren. Bei Bedarf verwende ich dann weitere Namespaces, um Namenskollisionen zu vermeiden. Dieser ConstantsNamespace ist selbst in einem Catch-All-Namespace für den Systemcode des Programms enthalten, mit einem Namen wie SysData. Dies schafft einen vollständig qualifizierten Namen , die drei oder vier Namensräume (wie SysData::Constants::ErrorMessages, SysData::Constants::Ailments::Bitflags, oder SysData::Defaults::Engine::TextSystem).
Justin Time - Stellen Sie Monica am

1
Wenn die Konstanten im tatsächlichen Code erforderlich sind, verwendet jede Funktion, die sie benötigt, eine usingAnweisung, um die entsprechenden Namen einzugeben, wodurch die Möglichkeit von Namenskonflikten minimiert wird. Ich finde, es verbessert die Lesbarkeit und hilft, die Abhängigkeiten eines bestimmten Codeblocks zu dokumentieren. Abgesehen von Konstanten neige ich dazu, es möglichst auf zwei Namespaces (wie SysData::Exceptionsund SysData::Classes) zu beschränken.
Justin Time - Stellen Sie Monica am

2
Insgesamt würde ich sagen, dass es im Allgemeinen am besten ist, eine minimale Anzahl verschachtelter Namespaces zu verwenden. Wenn Sie jedoch aus irgendeinem Grund globale Objekte benötigen (ob konstant oder veränderlich, vorzugsweise die ersteren), sollten mehrere verschachtelte Namespaces verwendet werden um sie in geeignete Kategorien zu unterteilen, um sowohl ihre Verwendung zu dokumentieren als auch mögliche Namenskollisionen zu minimieren.
Justin Time - Wiedereinsetzung Monica

2
-1 für "Bitte nicht tun" ohne objektive Gründe (trotz der späteren Klarstellungen). Die Sprache unterstützt verschachtelte Namespaces, und ein Projekt kann gute Gründe für deren Verwendung haben. Eine Diskussion möglicher solcher Gründe und konkreter objektiver Nachteile würde meine Ablehnung umkehren.
TypeIA

4

Hier ein Zitat aus Lzz (Lazy C ++) docs:

Lzz erkennt die folgenden C ++ - Konstrukte:

Namespace-Definition

Ein unbenannter Namespace und alle beigefügten Deklarationen werden in die Quelldatei ausgegeben. Diese Regel überschreibt alle anderen.

Der Name eines benannten Namespace kann qualifiziert sein.

   namespace A::B { typedef int I; }

ist äquivalent zu:

   namespace A { namespace B { typedef int I; } }

Natürlich ist die Qualität der Quellen, die von solchen Tools abhängt, umstritten ... Ich würde sagen, es ist eher eine Kuriosität, die zeigt, dass die durch C ++ induzierte Syntaxkrankheit viele Formen annehmen kann (ich habe auch meine ...)


2

Beide Standards (C ++ 2003 und C ++ 11) weisen sehr deutlich darauf hin, dass der Name des Namespace ein Bezeichner ist. Dies bedeutet, dass explizit verschachtelte Header erforderlich sind.

Mein Eindruck, dass dies keine große Sache ist, um neben einem einfachen Namen des Namespace einen qualifizierten Bezeichner zu platzieren, aber aus irgendeinem Grund ist dies nicht zulässig.


1

Sie können diese Syntax verwenden:

namespace MyCompany {
  namespace MyModule {
    namespace MyModulePart //e.g. Input {
      namespace MySubModulePart {
        namespace ... {
          class MyClass;
        }
      }
    }
  }
}

// Here is where the magic happens
class MyCompany::MyModule::MyModulePart::MySubModulePart::MyYouGetTheIdeaModule::MyClass {
    ...
};

Beachten Sie, dass diese Syntax auch in C ++ 98 gültig ist und fast der in C ++ 17 mit verschachtelten Namespace-Definitionen verfügbaren ähnelt .

Glücklich unnesting!

Quellen:


Dies ist die in der Frage erwähnte Systemsteuer, bei der stattdessen nach einer besseren Lösung gesucht wird. Jetzt ist mit C ++ 17 eine gültige Alternative verfügbar, wie in der akzeptierten Antwort angegeben. Entschuldigung, stimmen Sie ab, wenn Sie die Frage und Antwort nicht gelesen haben.
Beachwalker

@Beachwalker Lassen Sie uns nicht in die Syntax eintauchen. Die obige Namespace-Deklaration könnte genauso gut dieselbe sein wie in der akzeptierten Antwort. Der Hauptpunkt, den ich mit dieser Antwort hervorheben wollte, ist, was der OP gesagt hat, dass er verpasst hat, und was ich unter diesem Namespace-Durcheinander getan habe. Soweit ich sehen kann, scheint sich jeder darauf konzentriert zu haben, alles innerhalb des Namespace zu deklarieren, während meine Antwort Sie aus dem verschachtelten Durcheinander herausholt und ich bin sicher, dass OP diese Syntax geschätzt hätte, wenn jemand sie vor 4 Jahren bei dieser Frage erwähnt hätte wurde zuerst gefragt.
smac89

1

Dieses Papier behandelt das Thema ziemlich gut: Namespace-Papier

Was im Grunde genommen darauf hinausläuft. Je länger Ihre Namespaces sind, desto wahrscheinlicher ist es, dass Benutzer die using namespaceRichtlinie verwenden.

Wenn Sie sich also den folgenden Code ansehen, sehen Sie ein Beispiel, bei dem dies Ihnen schaden wird:

namespace abc { namespace testing {
    class myClass {};
}}

namespace def { namespace testing {
    class defClass { };
}}

using namespace abc;
//using namespace def;

int main(int, char**) {
    testing::myClass classInit{};
}

Dieser Code wird jedoch gut kompiliert. Wenn Sie die Zeile //using namespace def;auskommentieren, wird der "Test" -Namensraum mehrdeutig und es treten Namenskollisionen auf. Dies bedeutet, dass Ihre Codebasis durch Einfügen einer Bibliothek eines Drittanbieters von stabil zu instabil wechseln kann.

Selbst wenn Sie in C # verwenden using abc;und using def;der Compiler dies erkennen kann testing::myClassoder myClasssich nur im abc::testingNamespace befindet, erkennt C ++ dies nicht und es wird als Kollision erkannt.


0

Ja, du musst es so machen

namespace A{ 
namespace B{
namespace C{} 
} 
}

Sie versuchen jedoch, die Namespaces so zu verwenden, dass sie nicht verwendet werden sollen. Überprüfen Sie diese Frage, vielleicht finden Sie sie nützlich.


-1

[BEARBEITEN:]
Da verschachtelte C ++ 17-Namespaces als Standardsprache unterstützt werden ( https://en.wikipedia.org/wiki/C%2B%2B17 ). Ab sofort wird diese Funktion in g ++ 8 nicht unterstützt, sie befindet sich jedoch im Compiler in clang ++ 6.0.


[SCHLUSSFOLGERUNG:]
Verwenden Sie clang++6.0 -std=c++17als Standardkompilierungsbefehl. Dann sollte alles gut funktionieren - und Sie können mit namespace OuterNS::InnerNS1::InnerNS2 { ... }in Ihren Dateien kompilieren .


[URSPRÜNGLICHE ANTWORT:]
Da diese Frage etwas alt ist, gehe ich davon aus, dass Sie weitergezogen sind. Aber für andere, die immer noch nach einer Antwort suchen, kam mir die folgende Idee:

Emacs-Puffer mit Hauptdatei, Namespace-Dateien, Kompilierungsbefehl / -ergebnis und Befehlszeilenausführung.

(Darf ich hier Werbung für Emacs machen :)?) Das Posten eines Bildes ist viel einfacher und lesbarer als das einfache Posten von Code. Ich habe nicht die Absicht, alle Eckfälle vollständig zu beantworten, sondern wollte mich nur inspirieren lassen. (Ich unterstütze C # voll und ganz und bin der Meinung, dass C ++ in vielen Fällen einige OOP-Funktionen übernehmen sollte, da C # hauptsächlich aufgrund seiner vergleichbaren Benutzerfreundlichkeit beliebt ist.)


Update: Da C ++ 17 einen verschachtelten Namespace hat ( nuonsoft.com/blog/2017/08/01/c17-nested-namespaces ), scheint meine Antwort nicht mehr relevant zu sein, es sei denn, Sie verwenden ältere Versionen von C ++ .
ぐ イ き ん

1
So sehr ich Emacs liebe, ist es nicht ideal, ein Bild zu veröffentlichen. Es entzieht sich der Textsuche / -indizierung und erschwert den Zugriff auf Ihre Antwort für sehbehinderte Besucher.
Heinrich unterstützt Monica
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.