55 votes

Pourquoi ne puis-je pas déclarer une classe dans un espace de nom comme celui-ci ?

class Namespace::Class;

Pourquoi dois-je faire ça ?

namespace Namespace {
    class Class;
}

En utilisant VC++ 8.0, le compilateur pose des problèmes :

error C2653 : 'Namespace' : n'est pas un nom de classe ou d'espace de nom

Je suppose que le problème ici est que le compilateur ne peut pas dire si Namespace est une classe ou un espace de nom ? Mais pourquoi cela a-t-il de l'importance puisqu'il s'agit juste d'une déclaration en avant ?

Existe-t-il un autre moyen de déclarer une classe définie dans un espace de noms ? La syntaxe ci-dessus donne l'impression de "rouvrir" l'espace de noms et d'étendre sa définition. Et si Class n'ont pas été réellement définis dans Namespace ? Cela entraînerait-il une erreur à un moment donné ?

1voto

StoryTeller Points 6139

Il y a beaucoup d'excellentes réponses sur le raisonnement impliqué dans le refus de l'interdire. Je veux juste fournir la clause standard ennuyeuse qui l'interdit spécifiquement. Ceci est valable pour C++17 (n4659).

Le paragraphe en question est [nom.de la classe]/2 :

Une déclaration consistant uniquement en identifiant de la clé de classe ; il s'agit soit d'une redéclaration du nom dans la portée courante ou une déclaration avant de l'identificateur en tant que nom de classe. Il introduit le nom de la classe dans la portée courante.

Ce qui précède définit ce qui constitue une déclaration forward (ou redéclaration d'une classe). Essentiellement, il doit s'agir de l'un des éléments suivants class identifier; , struct identifier; o union identifier;identifiant est la définition lexicale commune dans [lex.name] :

identifier:
  identifier-nondigit
  identifier identifier-nondigit
  identifier digit
identifier-nondigit:
  nondigit
  universal-character-name
nondigit: one of
  a b c d e f g h i j k l m
  n o p q r s t u v w x y z
  A B C D E F G H I J K L M
  N O P Q R S T U V W X Y Z _
digit: one of
  0 1 2 3 4 5 6 7 8 9

Qui est la production du régime commun [a-zA-Z_][a-zA-Z0-9_]* que nous connaissons tous. Comme vous pouvez le voir, cela exclut class foo::bar; d'être une déclaration prospective valide, car foo::bar n'est pas un identifiant. C'est un nom entièrement qualifié, quelque chose de différent.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X