Considerar este código,

template<class T>
struct Sample
{ 
     typename T::X *x; //declare pointer to T's X
};

En el código de arriba, la palabra clave typename es requerido por el compilador, por lo que se puede diferenciar entre los tipos anidados anidadas y de valores en las plantillas. Eso significa que, en ausencia de typename palabra clave, el compilador podría interpretar esto como la multiplicación de T::X con x,

T::X *x; //multiply T::X with x

Por lo que en tales situaciones en donde la ambigüedad puede surgir, la palabra clave typename se convierte en necesidad así como para eliminar ambigüedades. Pero hay algunas situaciones en el contexto propio elimina ambigüedades. El otro tema analiza los contextos de la clase de base y en función de los parámetros (esto último no quita la ambigüedad, aunque). En este tema, particularmente, quiero hablar de otros dos contextos que parecen ser inequívoca, pero todavía estamos obligados a escribir typename,

typedef typename T::X xtype;
pX = new typename T::X;  

En estas dos situaciones, las palabras clave typedef y new hacer que sea lo suficientemente clara como para que el compilador que lo que sigue es tipo, no valor.

Así que mi pregunta es, ¿por qué compiladores todavía necesita la typename palabra clave, incluso en inequívoca situaciones tales como cuando usamos typedef y new?


EDICIÓN (después de leer esta respuesta de Johannes Schaub) :

//typedef NOT followed by a type!
int typedef A;

Esta sintaxis me pide modificar mi pregunta sea un poco, de modo que el punto que estoy tratando de hacer, puede ser visto por otros.

Considerar esto,

T::X typedef *x;

Por lo que desde el contexto, es todavía lo suficientemente clara como para que el compilador que T::X es un tipo, no importa si parece antes de typedef,o después de typedef. A menos que C++ nos permite escribir typedef 5 five o typedef T::value t_value (donde T::el valor es valor), la presencia de typedef sí elimina todas las ambigüedades y así, typename parece innecesario el requisito de la Norma (en este tipo de situaciones). El mismo argumento vale para new así.


También, he escrito una clase de plantilla que está utilizando esta estructura como argumento de plantilla:

struct A 
{
        struct X { string name; };
        static const int X = 100;
};

Particularmente, quiero saber si el código siguiente (desde el constructor) es correcta (portátil) o no,

//two interesting statements
 pX = new typename T::X; //T::X means struct X
 product = T::X * p; //but here, T::X means int X

El código completo se aquí en ideone. Por favor, eche un vistazo antes de responder. 🙂

  • Y la pregunta es?
  • su pregunta es ¿por qué el compilador necesita un typename palabra clave después de typedef. causa después de typedef siempre sabe un tipo string es Commin. Sin embargo, yo creo que Esto es como el Analizador sintáctico está escrito.
  • la pregunta es : ¿por Qué los compiladores todavía necesita el nombre de la palabra clave en inequívoca de situaciones?
  • Esta es la Regla de escritura de la sintaxis.es realmente necesario para hacer un significado Fuera de él ? Lo que viene incluso después de typedef debe ser de un tipo. así que usted debe typename ella. Los compiladores nunca se sabe después de typedef su obtención de un tipo. Más bien se espera que el próximo token sería un tipo. y typename confirma que.
  • su razonamiento no es convincente para mí, ya que si después de typedef compilador no encuentra el tipo, entonces se daría error de compilación como se habría dado si se hubiera usado el nombre también.
  • Al parecer, el compilador no las necesita. Mira MSVC! 🙂

InformationsquelleAutor Nawaz | 2010-12-12

3 Comentarios

  1. 14

    Sintaxis de C++ es más loco que eso.

    //typedef NOT followed by a type!
    int typedef A;
    
    //new NOT followed by a type!
    new (0) int;

    Otros han comentado acerca de su ejemplo. El typename especificador de no ceder a la búsqueda de ignorar no-tipo de nombres. Así que si usted dice new typename T::X, y no es un nombre de objeto X en T, todavía se encuentran en lugar del nombre del tipo de X (GCC sin embargo ignora que no escriba los nombres en la búsqueda de un nombre después de un typename. Pero eso no es compatible con los Estándares).


    Respuestas a las ediciones:

    Considerar esto,

    T::X typedef *x;

    Por lo que desde el contexto, es todavía lo suficientemente clara como para que el compilador que T::X es un tipo, no importa si aparece antes de typedef,o después de typedef.

    El compilador tiene que saber cuando la declaración de los prescriptores y de los i.e la «sección tipo» y cuando la sentencia declarativa de la sección inicio (i.e los «nombres» de la sección). Hay declaraciones donde la sección tipo está vacía:

    //constructor definitions don't need a type section
    MyClass::MyClass() { }
    
    //conversion function definitions don't need a type section
    MyClass::operator int() { }

    Si el primer nombre que especifique no es un tipo, el tipo de los extremos de la sección, y el nombre de la sección que comienza. Diciendo T::X le dice al compilador:

    Ahora quiero definir T::X.

    Se lee de izquierda a derecha, por lo que creo que se le olvidó un punto y coma cuando, a continuación, encuentra la typedef. Dentro de las clases de la interpretación es un poco diferente pero parecido a esto también. Eso es simple y eficaz para analizar.

    Mismo argumento es válido para las nuevas también.

    Tiendo a estar de acuerdo con usted aquí. Sintácticamente debe ser inequívoca si de salir fuera de los paréntesis. Como yo nunca he escrito un C++ analizador, puede haber trampas ocultas que no estoy viendo, aunque.

    Cada adición de typename en la esquina de los casos de la lengua, como en new potencialmente requieren una cantidad sustancial de diseño de compiladores y redactores de normas, mientras que sigue exigiendo la typename para la inmensa mayoría de los casos donde se necesita. No creo que este vale la pena.

    • Gracias por este precioso post. Al menos hoy me enteré de esta nueva sintaxis de typedef. Pero creo que, aún no tiene respuesta a mi pregunta de manera satisfactoria. Por favor, lea el editado parte de mi post!!!
  2. 0

    Entonces, ¿por qué compiladores todavía necesita el nombre de la palabra clave?

    Porque las reglas de la lengua están formulados de manera que: cada cargo nombre que se utiliza en un tipo de contexto debe ser precedida por typename (mutatis mutandis, lo mismo ocurre para el nombre de la plantilla y template palabra clave). Ahora, ¿por qué las reglas de la lengua no hacen la diferencia entre los casos en que el nombre es necesario para eliminar la ambigüedad y aquellos en los que el contexto proporciona suficiente información? Probablemente, yo no estaba allí cuando la decisión fue tomada para proteger la descripción del lenguaje para ser aún más complejo (considerar las consecuencias de la falta de los casos, de una manera o de la otra).

    En tu ejemplo, X no es un nombre de tipo (que la posibilidad de que si para la compatibilidad con C, donde el nombre de la etiqueta no son automáticamente el nombre del tipo), por lo que necesita para yuse struct:

    pX = new struct T::X;
  3. 0

    El código parece ir en una zona muy gris.

    Este párrafo sobre la ocultación de nombres

    Un nombre de clase (9.1) o nombre de enumeración
    (7.2) puede ser ocultado por el nombre de un
    variable, de los datos miembro, de la función, o
    enumerador declarado en el mismo ámbito.
    Si una clase o nombre de enumeración y una
    variable, de los datos miembro, de la función, o
    enumerador se declaran en el mismo
    ámbito de aplicación (en cualquier orden) con la misma
    nombre de la clase o nombre de enumeración es
    oculto donde la variable, los datos
    miembro, una función o un enumerador nombre
    es visible.

    parece indicar que el compilador es el derecho a quejarse de que A::X no es un nombre de tipo.

    • eso no es convincente, ya que cualquier sugerencia compilador puede obtener a partir del uso de typename (en estos dos casos), la misma sugerencia de que el compilador puede llegar incluso a partir del uso de typedef y new.
    • Yo estaba más preocupado con la ocultación de nombres. struct X {}; int X; typedef X Y; – el compilador sólo ve el entero denominado X. AProgrammer es sobre algo, sin embargo, porque typedef struct X Y; «muestra» de ella.
    • incluso en ese caso typedef y new pueden jugar el mismo papel que se espera que los typename para jugar. La idea de typename es dar una pista al compilador que lo que sigue es type, entonces esta sugerencia compilador ya se puede obtener cuando se analiza las palabras clave typedef o new.

Dejar respuesta

Please enter your comment!
Please enter your name here