2010-01-27 14 views
8

La siguiente línea de código se compila bien y se comporta:typedef y contenedores de punteros const

list<const int *> int_pointers; // (1) 

Las siguientes dos líneas no:

typedef int * IntPtr; 
list<const IntPtr> int_pointers; // (2) 

tengo la misma exacta errores de compilación para

list<int * const> int_pointers; // (3) 

Soy consciente de que la última línea no es legal ya que los elementos de un contenedor STL deben ser asignable. ¿Por qué la interpretación del compilador (2) es la misma que (3)?

Respuesta

9

Respuesta corta:

  1. es una lista de punteros a enteros constantes.
  2. es una lista de punteros constantes a ints.
  3. es el mismo que 2.

const (y volátiles) debe aparecer de forma natural después de que el tipo califican. Cuando se escribe antes, el compilador reescribe automáticamente internamente:

const int * 

convierte

int const * 

que es un puntero a un int constante. Las listas de estos compilarán bien, ya que el puntero en sí todavía es asignable.

8

Lea las declaraciones de tipo C de derecha a izquierda. Así que "const int *" es un puntero a constantes constantes ("const int" e "int const" significan lo mismo). Esos son perfectamente asignables. Pero (2) y (3) son punteros constantes a int, y por lo tanto no asignables.

5

const IntPtr y const int* no son lo mismo.

1) const int* es "puntero a const int".

2) const IntPtr expande a int * const (piensa (int *) const) que es "const puntero a int".

En resumen, el typedef actúa como un conjunto de paréntesis. No puede cambiar const -ness de lo que indica un puntero typedef 'd.

3

const int * es lo mismo que escribir int const *, lo que significa un valor constante apuntado por un puntero no constante.

Con typedef define el puntero en sí mismo como constante, como en su tercera instrucción.

5

Se pregunta "¿Por qué la interpretación del compilador (2) es la misma que (3)?". Bueno, porque en el lenguaje C++ (así como también en C), son semánticamente iguales.Cuando se define un nombre de tipo como

typedef int *IntPtr; 

luego el tipo const IntPtr se presentará a int *const, no para const int *. Así es como funcionan los nombres typedef en C++.

Los nombres de nombre de archivo en C++ no son macros. Si bien no definen nuevos tipos (solo alias para los existentes), los alias resultantes son, sin embargo, "atómicos", "monolíticos" en el sentido de que los calificadores aplicados al alias se aplicarán como calificadores de nivel superior. Cuando trabaje con un typedef-name, no hay forma de "infiltrarse" en un calificador const para que de alguna manera "descienda" a una parte de nivel inferior del tipo (int en su caso).

Si usted insiste en el uso de typedef-nombres, que no tienen otra opción inmediata, sino para proporcionar dos typedef-nombres diferentes, como

typedef int *IntPtr; 
typedef const int *ConstIntPtr; 

y utilizar ConstIntPtr cuando se necesita una versión de puntero a const de el tipo.

+0

+1, buena respuesta :-) –

0

Estoy seguro de que sabe que const IntPtr y son del mismo tipo. Lo que significa list<const IntPtr> y list<IntPtr const> son del mismo tipo. Lo que significa que está tratando de compilar esto:

typedef int * IntPtr; 
     list<IntPtr const> int_pointers; // (2bis) 
Cuestiones relacionadas