class Namespace::Class;
¿Por qué tengo que hacer esto ?:
namespace Namespace {
class Class;
}
Usando VC ++ 8.0, el compilador emite:
error C2653: 'Espacio de nombres': no es un nombre de clase o espacio de nombres
Supongo que el problema aquí es que el compilador no puede decir si Namespace
es una clase o un espacio de nombres. Pero, ¿por qué importa esto ya que es solo una declaración adelantada?
¿Hay otra forma de declarar hacia adelante una clase definida en algún espacio de nombres? La sintaxis anterior parece que estoy "reabriendo" el espacio de nombres y extendiendo su definición. ¿Qué pasa si Class
no se definió realmente en Namespace
? ¿Esto resultaría en un error en algún momento?
c++
namespaces
Yong Li
fuente
fuente
A::B
elA
es un identificador de espacio de nombres en lugar de un nombre de clase?Namespace
es una clase o un espacio de nombres. Simplemente no se acerque al indicio de una posibilidad de iniciar una guerra de lenguaje sobre la sintaxis.Respuestas:
Porque no puedes En lenguaje C ++, los nombres totalmente calificados solo se usan para referirse a entidades existentes (es decir, previamente declaradas). No se pueden usar para introducir nuevas entidades.
Y usted está de hecho "reapertura" del espacio de nombres para declarar nuevas entidades. Si la clase
Class
se define más tarde como un miembro de un espacio de nombres diferente, es una clase completamente diferente que no tiene nada que ver con la que usted declaró aquí.Una vez que llegue al punto de definir la clase pre-declarada, no necesita "volver a abrir" el espacio de nombres nuevamente. Puede definirlo en el espacio de nombres global (o en cualquier espacio de nombres que incluya su
Namespace
) comoComo se refiere a una entidad que ya ha sido declarada en el espacio de nombres
Namespace
, puede usar el nombre calificadoNamespace::Class
.fuente
Estás obteniendo respuestas correctas, déjame intentar una nueva redacción:
class Namespace::Class;
Tienes que hacer esto porque el término
Namespace::Class
le dice al compilador:Pero el compilador no sabe de qué está hablando porque no conoce ningún espacio de nombres con nombre
Namespace
. Incluso si hubiera un espacio de nombres nombradoNamespace
, como en:todavía no funcionaría, porque no puede declarar una clase dentro de un espacio de nombres desde fuera de ese espacio de nombres. Tienes que estar en el espacio de nombres.
Por lo tanto, puede declarar una clase dentro de un espacio de nombres. Solo haz esto:
fuente
Supongo que es por la misma razón por la que no puede declarar espacios de nombres anidados de una sola vez así:
y tienes que hacer esto:
fuente
No estaría claro cuál es realmente el tipo de una variable declarada hacia adelante. La declaración adelantada
class Namespace::Class;
podría significaro
fuente
Hay muchas respuestas excelentes sobre la justificación involucrada en no permitirlo. Solo quiero proporcionar la aburrida cláusula estándar que específicamente lo prohíbe. Esto es cierto para C ++ 17 (n4659).
El párrafo en cuestión es [class.name] / 2 :
Lo anterior define lo que constituye una declaración directa (o una declaración roja de una clase). Esencialmente, debe ser uno de
class identifier;
,struct identifier;
ounion identifier;
donde identifer es la definición léxica común en [lex.name] :Cuál es la producción del esquema común con el
[a-zA-Z_][a-zA-Z0-9_]*
que todos estamos familiarizados. Como puede ver, esto impideclass foo::bar;
ser una declaración directa válida, yafoo::bar
que no es un identificador. Es un nombre totalmente calificado, algo diferente.fuente