Pregunta

¿Por qué es que el constructor único parámetro de std::list<T> requiere T ser un tipo predeterminado Urbanizable? Me refiero a la siguiente código no compila.

struct Foo { // does not have default constructor.
  Foo (int i) {} 
}
int main(void) {
  std::list<Foo> l(10);
}

Parece posible utilizar el construir y destruir los modismos como que ya se han hecho en el std :: vector, aunque con más libro de mantenimiento de la lista de la clase.

En una nota relacionada, por qué no tienen la función de la capacidad en la lista? Se puede argumentar que tal función pagaría la memoria de asignación de costos por adelantado y eliminar la sobrecarga más adelante a medida que push_back objetos. Al menos que hará que las interfaces de dos contenedores de secuencia STL ligeramente más consistente.

¿Fue útil?

Solución

std :: lista no tiene una función de su capacidad debido a que no tiene sentido; nunca se tiene que cambiar el tamaño de un vector como lo hace. Es la capacidad sólo está limitado por la memoria disponible, que no es fácil de determinar.

A partir de lo que usted pidió, creo que realmente desea reserva (). Eso es un hecho aislado para el vector, ya que (mal) necesita tal cosa; no hay requisito particular para realizar todas las funciones consistente en todos los contenedores STL, especialmente cuando tienen poco sentido para los demás.

Usted puede lograr el mismo efecto utilizando un asignador de costumbre. Como sugirió Manuel, mira impulso.

Otros consejos

No existe ningún requisito general de que el tipo sea construible por defecto - que debe ser copiable y asignable. Su código no funciona porque intenta crear una lista de 10 elementos - que tienen que ser construido de alguna manera y por lo que el constructor por defecto debe ser utilizado - pero sólo en este caso específico. Si ha creado una lista vacía y se agrega a ella, no habría tal requisito.

Lo mismo es cierto para otros recipientes - tratar de compilar el siguiente:

#include <vector>

struct A {
    A( int x ) : z(x) {}
    int z;
};

std::vector <A> a(10);

En cuanto a la segunda parte de su pregunta, me gustaría simplemente observo que la consistencia de la interfaz no fue un criterio de diseño principal de los contenedores estándar - no hay intención, por ejemplo, que un tipo de contenedor es un "drop-in "sustitución por otro. Hay una buena discusión sobre esto en los puntos 1 y 2 del libro de Scott Meyers 'STL eficaz'.

Neil ya respondió a la pregunta principal .

También tenga en cuenta que se necesita un constructor por defecto cuando se llama a cambiar el tamaño ().

Puede eludir esto por tener una lista de punteros a STL objetos, pero supongo que esto ya era obvio para usted.

  

En una nota relacionada, por qué no tener la   función de la capacidad en la lista? Usted puede   argumentan que tal función pagaría   la memoria de asignación de costos por adelantado y   eliminar la sobrecarga más adelante a medida que   push_back objetos. Al menos lo hará   hacer que las interfaces de dos STL   contenedores de secuencias ligeramente más   consistente.

Creo que el problema aquí es que listas STL permiten en todas las listas de empalme . Si desea asignar memoria por adelantado, echar un vistazo a la Boost piscina Allocator .

La razón es que, cuando se construye una lista de elementos de n (donde n es el parámetro que utilizó en el constructor), la lista llena su estructura de n elementos con copias de T ().

SGI STL para la documentación lista .

  

¿Por qué es que el único parámetro   constructor de std :: lista requiere T   ser un tipo predeterminado Urbanizable?

Debido a que este contructor - lista con los elementos (número que pasamos como parámetro) crea. Valor de cada elemento será por defecto. También se puede utilizar el constructor con dos parámetros, para la lista con los elementos que se inicializan con el segundo valor de elemento de crear.

  

En una nota relacionada, por qué no tener la   función de la capacidad en la lista?

No tiene sentido, porque el costo de añadir nuevos elementos a la lista es mucho más pequeña que en el caso con el vector.

  

std :: vector no tiene tal   restricción. Mi pregunta es ¿por qué no   utilizar las mismas técnicas   (Crear / destruir los modismos) en el   std :: lista también?

No es restricción. Porque si no se utiliza como constructor, no se requiere de inicialización por defecto. Lo mismo ocurre con el vector.

Entonces, la pregunta es realmente "¿por qué no tienen funciones de las reservas y de capacidad en la lista?"

La respuesta a eso es que no hay ninguna razón para reservar memoria de antemano por la lista - la adición de nuevos elementos nunca requiere de un realloc y copiar los elementos existentes, no hay requisito de que la memoria que contiene el contenido de una lista sea contigua, y iteradores no ser invalidada cuando se hace una list::push_back().

Todos estos son la razón de la existencia de vector<>::reserve(), y tener memoria en reserva para nuevos elementos es por qué un vector<> llevará a cabo la colocación en la memoria new prima.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top