2011-08-21 13 views

Respuesta

10

Después de leer el tutorial, estaba un poco confundido por la redacción. Pero creo que es tan simple como esto: el tutorial se explica por qué cabecera de la plantilla del asignador muestra

allocator(const allocator&) throw();

y

template <class U> allocator(const allocator<U>&) throw();

pesar de que el constructor de copia es bastante inútil para un asignador. Y la respuesta fue que la especificación de un asignador no permite que el constructor genere excepciones. Por lo tanto, la interfaz pública del constructor de copias define los constructores de copias con una especificación de excepción de throw() (no arroja ninguna excepción) para evitar que alguien derive su propio asignador con constructores de copia que puedan arrojar una excepción.

Consulte this link para obtener una buena descripción de lo que es una especificación de excepción si eso es lo que le está tirando. (Sin juego de palabras. Realmente.)

Por lo tanto, no significa que al crear un asignador, debe proporcionar un constructor de copia. Simplemente señalaban que la especificación específicamente le prohíbe definir uno que arroje alguna excepción. `

1

El asignador requiere un constructor de copia porque los contenedores tienen un constructor de copia y necesitarán copiar su asignador en el proceso.

+1

Antes de C++ 11, los asignadores eran necesariamente apátridas. En consecuencia, llamar al constructor predeterminado sería suficiente.Después de C++ 11, si los asignadores se copian mediante sus contenedores adjuntos en una circunstancia determinada se determina mediante la presencia y la definición de los métodos de asignación de los asignadores 'select_on_container_X_Y'. Consulte la [referencia de los rasgos del asignador] (http://en.cppreference.com/w/cpp/memory/allocator_traits) – apmccartney

4

Tiene que escribir explícitamente un constructor de copia (en lugar de usar el predeterminado) porque el constructor de copia para un asignador C++ 03 debe definirse con el especificador de excepción throw(). El constructor de copia predeterminado no tiene este especificador.

Técnicamente, usted no tiene, pero si arroja una excepción ... bueno, buena suerte con eso.

Pero eso es solo una pequeña molestia, ya que los asignadores en C++ 03 no pueden tener estado. Entonces no deberías estar copiando miembros. El constructor de copia puede estar vacío.

+1

Nicol Bolas, ¿estará bien si el asignador (const allocator &) = delete ;? como estamos en 2016 –

0

En realidad es bastante simple. El constructor de un contenedor que usa un asignador toma el asignador y almacena una copia del mismo. Para hacer eso, necesita que el asignador sea CopyConstructible. Eso es todo. Tenga en cuenta que no se requiere un tipo de asignador a CopyAssignable a menos que su rasgo propagate_on_container_copy_assignment sea verdadero (lo cual es raro).

La especificación C++ 11 también establece que "Ningún constructor, operador de comparación, operación de copia, operación de movimiento o operación de intercambio en estos tipos saldrá a través de una excepción". Las reglas de excepción le permiten hacer una copia (pila) de un asignador (especialmente durante la construcción o destrucción) sin preocuparse de que se produzca la copia del asignador. Es casi imposible diseñar contenedores que sean a prueba de excepciones en presencia de asignadores que puedan arrojar al copiar, mover, intercambiar o comparar. En la práctica, un asignador no puede contener mucho más que un puntero a algún recurso, por lo que permitir que los asignativos arrojen en la copia, etc., agregaría mucho dolor prácticamente sin ganancia.

Cuestiones relacionadas