2012-05-01 17 views
10

Parece que no puedo encontrar ningún algoritmo estándar que demuestre el requisito para construir por defecto ForwardIterator.¿Por qué se requieren ForwardIterators para modelar DefaultConstructible?

¿Hay alguna razón real para ello, o puedo pasarlo por alto?

+4

No importa si hay una razón real para ello; es necesario*. Entonces ignore el requisito bajo su propio riesgo. –

+1

Bueno, si el iterador se basa lógicamente en un argumento, la alternativa es agregar constructores predeterminados que dejen el objeto en un estado no válido, lo que también parece flirtear con el peligro. – Ayjay

+0

Una alternativa * working * sería cambiar sus iteradores para que no se basen en un argumento. Póngalos en un estado válido pero conceptualmente vacío. –

Respuesta

4

Está destinado a facilitar el uso de este tipo de iteradores, tanto para los algoritmos estándar como para los usuarios de los clientes.

Por ejemplo (recordemos que RandomAccessIterator es un subtipo de ForwardIterator):

template <class RandomAccessIterator> 
    void sort (RandomAccessIterator first, RandomAccessIterator last) 
{ 
    RandomAccessIterator pivot, i, j; 
    //do your sorting algorithm   
} 

Si no se construible por defecto que se necesita para asignarlos a first o last sólo para que se compile.

No necesita que se establezca en un valor predeterminado. Cualquier uso de dicho iterador no inicializado no está definido. No es que no sería prudente agregar algo de control, particularmente en compilaciones de depuración.

Y no, no debe arrojar el constructor predeterminado. Sería técnicamente conforme, pero muchos algoritmos fallarán inesperadamente.

+0

Ese es un argumento para 'RandomAccessIterator' para modelar' DefaultConstructible', no 'ForwardIterator'. 'InputIterator' no es necesario para modelar' DefaultConstructible', ¿por qué 'ForwardIterator'? – Ayjay

+1

Sin mencionar, no sé si permitir una implementación dudosa más fácil de los algoritmos estándar vale la pena el requisito innecesario que no permite el uso de referencias y otros tipos no construibles por defecto. Tiene implicaciones de largo alcance en todos sus tipos de datos: de repente, todo lo que utiliza el iterador también debe permitir ahora la construcción predeterminada y un estado "construido pero no válido". – Ayjay

+0

Bueno, ese tipo de código estaría en contra de las directrices de codificación basadas en RAII, donde la inicialización es obligatoria en el punto de definición. – dirkgently

3

Desde mi copia del proyecto:

24.2.5 iteradores Adelante [forward.iterators]

una clase o un tipo incorporado X satisface los requisitos de una iterador adelante si

[...]

- X satisface los requisitos DefaultConstructible (20.2.1),

y luego:

20.2.1 requisitos argumento de plantilla

En general, no se requiere un constructor por defecto. Determinadas firmas de función de miembro de clase de contenedor especifican el constructor predeterminado como un argumento predeterminado . T() será una expresión bien definida (8.5) si se llama a una de esas firmas usando el argumento predeterminado (8.3.6).

Hay dos cosas a tener en cuenta aquí:

  • La primera línea nos dice que una ctor predeterminado rara vez se requiere (que casi responde a su pregunta)
  • El requisito es probablemente un indicio de que iterador la semántica debe ser compatible con los punteros, siendo estos últimos predecibles (lea para no romper el código existente).
+0

Esto parece implicar que ForwardIterator debe ser DefaultConstructible si usted llama a una de esas "firmas de función miembro de clase contenedor determinadas". ¿El estándar especifica cuándo debe ocurrir eso? – Ayjay

+0

@Ayjay: El estándar debe proporcionar cualquiera de las funciones de miembro. No puedo nombrar uno, pero no me sorprendería si no hubiera ninguno. Eso debería indicarme que esto fue una manera de evitar que los futuros escritores de la biblioteca se relajen. – dirkgently

Cuestiones relacionadas