class Namespace::Class;
Warum muss ich das tun?:
namespace Namespace {
class Class;
}
Unter Verwendung von VC ++ 8.0 gibt der Compiler folgende Probleme aus:
Fehler C2653: 'Namespace': ist kein Klassen- oder Namespace-Name
Ich gehe davon aus, dass das Problem hier darin besteht, dass der Compiler nicht erkennen kann, ob Namespace
es sich um eine Klasse oder einen Namespace handelt. Aber warum ist das wichtig, da es sich nur um eine Vorwärtserklärung handelt?
Gibt es eine andere Möglichkeit, eine in einem Namespace definierte Klasse vorwärts zu deklarieren? Die obige Syntax fühlt sich so an, als würde ich den Namespace "wieder öffnen" und seine Definition erweitern. Was wäre, wenn Class
nicht tatsächlich in definiert wären Namespace
? Würde dies irgendwann zu einem Fehler führen?
c++
namespaces
Yong Li
quelle
quelle
A::B
derA
eine Namespace-ID anstelle eines Klassennamens steht?Namespace
es sich um eine Klasse oder einen Namespace handelt. Kommen Sie nur nicht an den Hinweis heran, dass möglicherweise ein Sprachflammenkrieg um die Syntax beginnen könnte.Antworten:
Weil du nicht kannst. In der C ++ - Sprache werden vollständig qualifizierte Namen nur verwendet, um auf vorhandene (dh zuvor deklarierte) Entitäten zu verweisen . Sie können nicht zum Einführen neuer Entitäten verwendet werden.
Und Sie sind in der Tat des Namespace „Wiedereröffnung“ neue Einheiten zu erklären. Wenn die Klasse
Class
später als Mitglied eines anderen Namespace definiert wird, handelt es sich um eine völlig andere Klasse, die nichts mit der hier deklarierten zu tun hat.Sobald Sie auf den Punkt zu bekommen definieren die vordeklarierte Klasse, brauchen Sie nicht zu „öffnen Sie “ wieder den Namespace. Sie können es im globalen Namespace (oder in einem beliebigen Namespace, der Ihren umschließt
Namespace
) als definierenDa Sie sich auf eine Entität beziehen, die bereits im Namespace deklariert wurde
Namespace
, können Sie einen qualifizierten Namen verwendenNamespace::Class
.quelle
Sie erhalten die richtigen Antworten. Lassen Sie mich einfach versuchen, die Formulierung neu zu formulieren:
class Namespace::Class;
Sie müssen dies tun, weil der Begriff
Namespace::Class
dem Compiler sagt:Der Compiler weiß jedoch nicht, wovon Sie sprechen, da er keinen benannten Namespace kennt
Namespace
. Auch wenn es einen Namespace mit dem Namen gabNamespace
, wie in:Es würde immer noch nicht funktionieren, da Sie eine Klasse innerhalb eines Namespace nicht von außerhalb dieses Namespace deklarieren können. Sie müssen im Namespace sein.
Sie können also eine Klasse innerhalb eines Namespace deklarieren. Mach das einfach:
quelle
Ich nehme an, aus dem gleichen Grund können Sie verschachtelte Namespaces nicht auf einmal wie folgt deklarieren:
und du musst das tun:
quelle
Es wäre nicht klar, was der Typ einer vorwärts deklarierten Variablen tatsächlich ist. Die Vorwärtserklärung
class Namespace::Class;
könnte bedeutenoder
quelle
Es gibt viele ausgezeichnete Antworten auf die Gründe, warum es nicht erlaubt ist. Ich möchte nur die langweilige Standardklausel bereitstellen, die dies ausdrücklich verbietet. Dies gilt für C ++ 17 (n4659).
Der fragliche Absatz lautet [class.name] / 2 :
Das Obige definiert, was eine Vorwärtsdeklaration (oder Redclaration einer Klasse) darstellt. Im Wesentlichen muss es einer der folgenden sein,
class identifier;
,struct identifier;
oderunion identifier;
wo identifer ist die gemeinsame lexikalische Definition in [lex.name] :Welches ist die Produktion des gemeinsamen Schemas, mit dem
[a-zA-Z_][a-zA-Z0-9_]*
wir alle vertraut sind. Wie Sie sehen können, ist dies keineclass foo::bar;
gültige Vorwärtsdeklaration, dafoo::bar
es sich nicht um eine Kennung handelt. Es ist ein voll qualifizierter Name, etwas anderes.quelle