2009-10-29 10 views
8

El programa¿Por qué el complejo <double> * int no está definido en C++?

#include <complex> 
#include <iostream> 

int main() 
{ 
    std::complex<double> z(0,2); 
    int n = 3; 
    std::cout << z * n << std::endl; 
} 

C++ produce un error: no partido de ‘operador *’ en ‘z * n’. ¿Por qué?

Estoy compilando con g ++ 4.4.1. Quizás el compilador simplemente sigue el estándar de C++, en cuyo caso mi pregunta es: ¿por qué el estándar no permite esto?

Respuesta

14

Esto funciona:

#include <complex> 
#include <iostream> 

int main() 
{ 
    std::complex<double> z(0,2); 
    double n = 3.0; // Note, double 
    std::cout << z * n << std::endl; 
} 

Debido complejo se compone de dobles, se multiplica con dobles. En cuanto a la declaración:

template <typename T> 
inline complex<T> operator*(const complex<T>&, const T&); 

(El siguiente es gracias a dribeas) El compilador no se le permite realizar conversiones de tipo implícitas durante la deducción de la plantilla, por lo que al pasar una complex con T siendo double, y luego otro T siendo int, al intentar hacer coincidir la función que trata T como double hace que el segundo argumento se desajuste, y viceversa.

Por lo que se quiere trabajar, que tendría que tener una función definida similar a esto:

template <typename T, typename U> 
inline std::complex<T> operator*(std::complex<T> lhs, const U& rhs) 
{ 
    return lhs *= rhs; 
} 

que permite a la función para tomar tipos diferentes, lo que permite que el yeso se puede hacer cuando se llama a operator*=.

+0

creo que es porque compleja es una clase y el * está sobrecargado para esa clase, que no es un primitivo para que no se siga echando reglas en el compilador – ldog

+0

Gracias , He corregido el error sobre ambigüedad y mi falla al codificar el operador correctamente. (Debería haber hecho el segundo, pero el primero es una lección para mí.) – GManNickG

+0

La implementación del operador que proporcionó inicialmente no era incorrecta, solo se podía mejorar (y en un proyecto regular, la diferencia sería bastante pequeña). –

2

std::complex<T> Los operadores están definidos para tomar como argumento otras instancias complex<T>. La ruta de int a través de double a complex<double> es demasiado contorsionada para el lenguaje C++ para seguirla de acuerdo con el estándar (y con las enormes complicaciones que surgen de las conversiones de rueda libre y las cociones es difícil criticar que aspecto de la norma). Supongo que el caso súper especial de complex<double> que permite int s como operandos a sus operadores simplemente no se consideró frecuente e importante como para justificar la especificación de especializaciones de plantilla para ese caso extremadamente individual, teniendo en cuenta lo fácil que resulta para el programador emitir el int a double cuando eso es lo que realmente quieren -)

+0

-1: el estándar proporciona funciones libres simétricas para multiplicar un std :: complex por T. (C++ 03, 26.2.6 [lib.complex.ops] Operaciones complejas que no son miembros) –

Cuestiones relacionadas