2012-06-19 9 views
35

De acuerdo con la especificación ISO C++, § 26.2/2:¿Por qué C++ ordena que ese complejo solo se instancia para doble flotante, doble o larga?

El efecto de instanciar la plantilla complex para cualquier tipo distinto de float, double o long double está especificado.

¿Por qué los autores estándar agregarían explícitamente esta restricción? Esto lo hace no especificado, por ejemplo, lo que sucede si hace complex<int> o complex<MyCustomFixedPointType> y parece una restricción artificial.

¿Hay algún motivo para esta limitación? ¿Existe una solución si desea crear una instancia de complex con su propio tipo personalizado?

Principalmente estoy haciendo esta pregunta debido a this earlier question, en la cual el OP estaba confundido sobre por qué abs daba salidas extrañas para . Dicho esto, esto todavía no tiene sentido dado que también podríamos querer hacer complex números fuera de los tipos de puntos fijos, números reales de mayor precisión, etc.

+4

Tuve que reír después de ver su respuesta anterior, pero realmente es una buena pregunta. – chris

+9

@ chris- Me sentí mal al dar esa respuesta sin poder darle una razón de alto nivel. Normalmente soy bueno diciendo "este es un caso extremo extraño de C++ por razones X, Y y Z", pero esta vez no tengo idea de qué pasa. – templatetypedef

+4

"La estandarización del complejo se ha discutido en el comité de forma intermitente durante más de una década y existe una resistencia significativa por parte de al menos un proveedor para apoyarlo". http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-March/020398.html –

Respuesta

28

No puede implementar correctamente muchas de las operaciones std::complex en enteros. Por ejemplo,

template <class T> 
T abs(const complex<T> &z); 

para un complex<long> no puede tener T = long valor de retorno cuando los números complejos se representan como pares (real, imag), ya que devuelve el valor de sqrt(pow(z.real(), 2) + pow(z.imag(), 2)). Solo algunas de las operaciones tendrían sentido.

Peor aún, el constructor nombrado polar no se puede hacer confiable sin romper el constructor predeterminado y viceversa. El estándar debería especificar que los "enteros complejos" son Gaussian integers para que sean de alguna utilidad, y que uno de los constructores está severamente roto.

Finalmente, ¿cómo le gustaría que se sirva su "división de enteros complejos", y le gustaría un "resto complejo" con eso? :)

En resumen, creo que sería más sensato para especificar un tipo separado gaussian_int<T> con sólo unas pocas operaciones que soporte de injerto para el integrante T en std::complex.

+1

Es curioso cómo elegimos exactamente la misma función para ilustrar. :) –

+0

Gracias por introducir una razón matemática sólida para la decisión. Creo que esto proporciona una elegante razón teórica para la decisión. No había oído hablar de los enteros gaussianos, ¡gracias por haberlos mencionado! – templatetypedef

+0

@templatetypedef: Gracias y +1 por la pregunta. Nunca había considerado lo que sucedería cuando 'complex' fuera modelado en tipos integrales. [No soy matemático, sin embargo, y si alguien puede probar que estoy equivocado en esto, por favor hazlo]. –

12

Probablemente por compatibilidad con las funciones auxiliares. Por ejemplo:

template<class T> T abs (const complex<T>& x); 

Si T == int, abs volvería int, lo que significaría una pérdida masiva de precisión.

Cuestiones relacionadas