Pregunta

El programa C ++

#include <complex>
#include <iostream>

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

produce un error: no coincide con & # 8216; operador * & # 8217; en & # 8216; z * n & # 8217 ;. ¿Por qué?

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

¿Fue útil?

Solución

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 a que el complejo está compuesto de dobles, se multiplica por dobles. Mirando la declaración:

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

(Lo siguiente es gracias a dribeas ) El compilador no puede realizar conversiones de tipos implícitas durante la deducción de plantillas, por lo que pasando un complejo con T siendo doble , y luego otro T siendo int , al intentar hacer coincidir la función que trata T como double hace que el segundo argumento no coincida, y viceversa.

Para lo que quiere trabajar, debería tener una función definida similar a esta:

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

Lo que permite que la función tome diferentes tipos, lo que permite realizar la conversión al llamar al operator * = .

Otros consejos

Los operadores de

std :: complex < T > están definidos para tomar como argumentos otras instancias de complex < T > . La ruta desde un int a través de un double a un complex < double > es marginalmente demasiado retorcida / enrevesada para que el lenguaje C ++ la siga de acuerdo según el estándar (y con las enormes complicaciones que ya surgen de las conversiones y las coerciones de rueda libre, es difícil criticar ese aspecto del estándar). Supongo que el caso súper especial de complex < double > que permite int s no emitidos como operandos para sus operadores simplemente no se consideró frecuente e importante como para garantizar la especificación de especializaciones de plantilla para eso caso extremadamente individual, considerando cuán trivialmente fácil es para el programador lanzar el int al double cuando eso es lo que realmente quieren ! -)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top