class Namespace::Class;
Pourquoi dois-je faire cela?:
namespace Namespace {
class Class;
}
À l'aide de VC ++ 8.0, le compilateur émet:
erreur C2653: 'Namespace': n'est pas un nom de classe ou d'espace de noms
Je suppose que le problème ici est que le compilateur ne peut pas dire s'il Namespace
s'agit d'une classe ou d'un espace de noms? Mais pourquoi est-ce important puisqu'il ne s'agit que d'une déclaration anticipée?
Existe-t-il un autre moyen de déclarer en avant une classe définie dans un espace de noms? La syntaxe ci-dessus donne l'impression que je "rouvre" l'espace de noms et étend sa définition. Et si Class
n'étaient pas réellement définis dans Namespace
? Cela entraînerait-il une erreur à un moment donné?
c++
namespaces
Yong Li
la source
la source
A::B
leA
est un identifiant d'espace de noms au lieu d'un nom de classe?Namespace
soit une classe ou un espace de noms. Ne vous approchez pas de la possibilité de déclencher une guerre des flammes du langage sur la syntaxe.Réponses:
Parce que tu ne peux pas. En langage C ++, les noms complets ne sont utilisés que pour faire référence à des entités existantes (c'est-à-dire précédemment déclarées). Ils ne peuvent pas être utilisés pour introduire de nouvelles entités.
Et vous êtes en fait « réouverture » l'espace de noms de déclarer de nouvelles entités. Si la classe
Class
est définie plus tard comme membre d'un espace de noms différent, il s'agit d'une classe complètement différente qui n'a rien à voir avec celle que vous avez déclarée ici.Une fois que vous êtes arrivé au point de définir la classe pré-déclarée, vous n'avez pas besoin de «rouvrir» l'espace de noms à nouveau. Vous pouvez le définir dans l'espace de noms global (ou dans tout espace de noms englobant votre
Namespace
) commePuisque vous faites référence à une entité qui a déjà été déclarée dans l'espace de noms
Namespace
, vous pouvez utiliser un nom qualifiéNamespace::Class
.la source
Vous obtenez des réponses correctes, laissez-moi simplement essayer de reformuler:
class Namespace::Class;
Vous devez le faire car le terme
Namespace::Class
indique au compilateur:Mais le compilateur ne sait pas de quoi vous parlez car il ne connaît aucun espace de noms nommé
Namespace
. Même s'il y avait un espace de noms nomméNamespace
, comme dans:cela ne fonctionnerait toujours pas, car vous ne pouvez pas déclarer une classe dans un espace de noms depuis l'extérieur de cet espace de noms. Vous devez être dans l'espace de noms.
Ainsi, vous pouvez en fait déclarer une classe dans un espace de noms. Faites juste ceci:
la source
Je suppose que c'est pour la même raison que vous ne pouvez pas déclarer les espaces de noms imbriqués en une seule fois comme ceci:
et vous devez faire ceci:
la source
Il ne serait pas clair quel est réellement le type d'une variable déclarée avant. La déclaration anticipée
class Namespace::Class;
pourrait signifierou
la source
Il y a beaucoup d'excellentes réponses sur la justification de son refus. Je veux simplement fournir la disposition standard ennuyeuse qui l'interdit spécifiquement. Cela est vrai pour C ++ 17 (n4659).
Le paragraphe en question est [class.name] / 2 :
Ce qui précède définit ce qui constitue une déclaration avant (ou redclaration d'une classe). Essentiellement, il doit être l'un des
class identifier;
,struct identifier;
ouunion identifier;
où identifer est la définition lexicale courante dans [lex.name] :Quelle est la production du schéma commun que
[a-zA-Z_][a-zA-Z0-9_]*
nous connaissons tous. Comme vous pouvez le voir, cela empêcheclass foo::bar;
d'être une déclaration avant valide, car cefoo::bar
n'est pas un identificateur. C'est un nom pleinement qualifié, quelque chose de différent.la source