2012-05-10 34 views
9

El siguiente código se compila y funciona bien en C (al menos según 'gcc -std = gnu99'), pero no se puede compilar en C++, dando "línea 5: error: no se puede convertir 'doble' en 'doble complejo 'en inicialización ". ¿Alguien sabe por qué?C ¿Números complejos en C++?

#include "/usr/include/complex.h" 
#include <stdio.h> 

int main(int argc, char * argv[]) { 
    double complex a = 3; // ERROR ON THIS LINE 
    printf("%lf\n", creal(a)); 
    return 0; 
} 

que darse cuenta de que hay otra manera de hacer los números complejos en C++, pero tengo que usar números complejos C en C++, porque así es como el código de la herencia que me dieron hace las cosas. ¡Gracias si puedes ayudar!

+4

Pero, en realidad, no _por qué_ Qué desea utilizar [ 'std :: compleja <>'] (http: // en.cppreference.com/w/cpp/numeric/complex)? – ildjarn

+2

FTR, '-std = gnu99' no es realmente la bandera que desea para ** C **. Eso es "C con cosas que GNU pensó sería una buena idea, pero si lo es o no depende de la interpretación". '-std = c99' es deseable si quieres ** C **. –

+0

ildjarn: Desafortunadamente, la biblioteca con la que estoy trabajando usa números complejos C99 en C++. No parece prudente comenzar un proyecto de esta manera, pero este es el código con el que tengo que trabajar. Martinho: es verdad Debería haber hecho la prueba con -std = c99 – iloveponies

Respuesta

10

Usar la palabra clave C para el complejo: _Complex. C++ utiliza una clase compleja como (plantilla). No estoy seguro de dónde está la creal o no lo comentaría.

#include <complex.h> 
#include <cstdio> 

int main(int argc, char * argv[]) { 
    double _Complex a = 3.0 + 0.0I; // DECLARATION WORKS NOW - NOTE ASSIGNMENT MUST HAVE IMAG PART 
    //printf("%lf\n", creal(a)); 
    return 0; 
} 

Esto funciona en gcc (compilé con g ++). Recibí una advertencia sobre los encabezados .h obsoletos.

Here es un enlace a un seguimiento de correo electrónico que muestra compatibilidad no estándar con C++ y C con números complejos. C++ 11 requiere compatibilidad de diseño de complejos C++ con C _Complexes.

Actualmente estoy investigando creal, etc. en C++. No encuentro nada en el estándar. Dado que parece haber algún esfuerzo para proporcionar compatibilidad de fuente entre C++ y C, entonces, creal, cpow, etc. pueden ser una buena adición a TR2 las propuestas de la biblioteca.

+0

¡GRACIAS! Por lo que dijiste, pude obtener la solución. Stack Overflow no me permite publicar la solución aún, pero es que debes agregar la parte imaginaria a la tarea. – iloveponies

9

Compatibility of C and C++

Several additions of C99 are not supported in C++ or conflict with C++ features, such as variadic macros, compound literals, designated initializers, variable-length arrays, and native complex-number types. The long long int datatype and restrict qualifier defined in C99 are not included in the current C++ standard, but some compilers such as the GNU Compiler Collection[4] provide them as an extension. The long long datatype along with variadic templates, with which some functionality of variadic macros can be achieved, are present in the new C++ standard, C++11. On the other hand, C99 has reduced some other incompatibilities by incorporating C++ features such as // comments and mixed declarations and code.

15

Un compilador de C++ podría elegir admitir la palabra clave _Complex como una extensión (y algunas lo hacen), pero eso no es portátil. Si desea tener una solución portátil de C++, debe utilizar las plantillas de C++ std :: complex, desafortunadamente.

La buena noticia es que C++ std :: números complejos se garantiza que sean compatibles con C números complejos (en el sentido de que un puntero a uno siempre se puede convertir en un puntero al otro, y lo correcto sucederá), lo que significa que si necesita interoperar con una biblioteca C que espera valores complejos C, no tendrá ningún problema.

C11:

Each complex type has the same representation and alignment requirements as an array type containing exactly two elements of the corresponding real type; the first element is equal to the real part, and the second element to the imaginary part, of the complex number.

C++ 11:

If z is an lvalue expression of type cv std::complex<T> then:

— the expression reinterpret_cast<cv T(&)[2]>(z) shall be well-formed,

reinterpret_cast<cv T(&)[2]>(z)[0] shall designate the real part of z , and

reinterpret_cast<cv T(&)[2]>(z)[1] shall designate the imaginary part of z .

+0

¿Dónde está esa garantía ("C++ std :: números complejos están garantizados para ser compatibles con los números complejos C99")? La respuesta a continuación (http://stackoverflow.com/a/10540288/2189128) cita una fuente no canónica (Wikipedia) que dice lo contrario. – Jeff

+2

@Jeff: El enlace de la wikipedia en realidad no contradice mi afirmación; son tipos diferentes, pero se garantiza que tienen el mismo diseño de memoria y requisitos de alineación. Agregué las referencias apropiadas a mi respuesta. –