2011-10-17 10 views
18

Ésta es una buena matriz de edad C:matrices constantes

int a[10]; 

Y esta es una buena gama de edad C que es const:

const int b[10]; 

En C++, parece que hay dos maneras de definir std::array s que son const:

std::array<const int, 10> c; 
const std::array<int, 10> d; 

son estas dos definiciones equi valent? Si es así, ¿cuál es el idiomático? Si no es así, ¿cuáles son las diferencias?

Respuesta

9

Bueno, el const int b[10]; original solo es útil cuando puede inicializar la matriz, por lo que los dos ejemplos de std::array no funcionan en la práctica.

1:

std::array<const int, 10> c; 

Este es el más cercano a const int c[10];. El problema es que no habrá ningún constructor predeterminado para él, y dado que los elementos no son mutables, no vale la pena usar esto. Debe proporcionar alguna inicialización para ello en el constructor. Tal como está, dará un error de compilación porque el constructor predeterminado no inicializó los elementos.

Este código significa que c es mutable, pero los elementos en sí no lo son. En la práctica, sin embargo, no hay mutaciones en c que no afecten a los elementos.

2:

const std::array<int, 10> d; 

Esto significa d no es mutable, pero los elementos son de tipo mutable int. Debido a que const se propagará a los miembros, significa que la persona que llama aún no puede cambiar los elementos. Similar al ejemplo anterior, necesitará inicializar d porque es const.

En la práctica, se comportan de manera similar tanto con respecto a la mutabilidad, ya que las operaciones mutables en array siempre tocan los elementos.

5

La definición superior asigna una matriz de enteros constantes en la pila, mientras que la segunda asigna una matriz constante de enteros variables. En el primer caso, debe definir el contenido de la matriz cuando la declare, ya que su contenido es constante y no puede modificarse más tarde. Supongo, la primera, segunda declaración también va a generar algo así como

const std::array<const int,10> c; 

desde una matriz estática siempre se asigna en la pila y el puntero a su primer elemento no puede ser modificado posteriormente.

+1

+1 aunque una matriz estática nunca se asigna en la pila. Se puede asignar una matriz _fixed size_ en la pila (declspec de almacenamiento automático) o en un segmento de datos global (declspec de almacenamiento estático). Trivia: en 'typedef int ints_t [10]; ints_t * ints = new ints_t(); 'is' ints' una matriz de tamaño fijo o una matriz dinámica? – sehe

+3

Ambas matrices requieren inicialización cuando se declaran. En mi humilde opinión, no hay diferencia entre los dos: son exactamente los mismos desde una perspectiva algorítmica y de uso (prácticamente, los iteradores son iguales; 'const int *'). Francamente, la mejor manera de declarar es como dices en la respuesta, 'const std :: array c;' Esto lo hace muy específico, una matriz de constricciones. – Nim

5

no son equivalentes - c.reference es int& mientras que d.reference es const int& (no es que se puede utilizar esa sintaxis para acceder typedefs, pero se podía capturar el tipo de plantilla de deducción de argumento y decir la diferencia).

Pero estoy bastante seguro de que tenfour tiene la observación clave, "no hay mutaciones en c que no afecten a los elementos".Así que, en lo que respecta a todo lo que realmente le haces a las matrices, son las mismas, simplemente tienen diferentes metadatos debido a sus diferentes tipos.

El caso principal en el que puedo pensar que marcaría la diferencia es si usa el tipo en sí en una interfaz (en lugar de tomar un parámetro de iterador o de plantilla de rango). Diría que al tomarlo como un puntero o parámetro de referencia, debería const-calificar el tipo array, ya que no le cuesta nada y le permite a la persona que llama usar su función, cualquiera que sea la elección que haya realizado. Usted puede const-califica el tipo de elemento, pero cualquiera que use es incompatible con el otro, por lo que básicamente todos deben aceptar cuál usar o de lo contrario se requerirá alguna copia. Eso requiere una coordinación activa en cuanto al estilo, creo, ya que dudo que consigas que todos en el mundo acuerden cuál es el mejor. const int probablemente tenga el mejor de los casos, sobre el principio de que debe const todo lo que pueda, pero supongo que int es lo que las personas usarán que no lo hayan pensado en absoluto, ya que están acostumbrados a todos esos contenedores C++ 03 que no puede tener un tipo de valor const.