2009-10-29 8 views
8

Il programmaPerché il complesso è <double> * int non definito in 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 errore: non può competere ‘operatore *’ a ‘z * n’. Perché?

Sto compilando con g ++ 4.4.1. Forse il compilatore sta solo seguendo lo standard C++, nel qual caso la mia domanda è: perché lo standard non lo consente?

risposta

14

Questo funziona:

#include <complex> 
#include <iostream> 

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

Perché complesso si compone di doppi, si moltiplica con doppie. Guardando la dichiarazione:

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

(Il seguente è grazie a dribeas) Il compilatore non è consentito effettuare conversioni di tipo implicite nel modello deduzione, così facendo passare un complex con T essendo double, e poi un altro T è int, quando si cerca di far corrispondere la funzione che tratta T come double causa la corrispondenza errata del secondo argomento e viceversa.

Per quello che si desidera lavorare, si dovrebbe avere una funzione definita simile a questo:

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

che permette la funzione di prendere tipi diversi, che permette il cast da compiere quando si chiama operator*=.

+0

Penso proprio perché complesso è una classe e la * è sovraccarico per quella classe, la sua non è una primitiva in modo che non segue la fusione regole nel compilatore – ldog

+0

Grazie , Ho corretto l'errore relativo all'ambiguità e il mio errore nel codificare correttamente l'operatore. (Avrei dovuto fare il secondo, ma la prima è una lezione per me.) – GManNickG

+0

L'implementazione dell'operatore inizialmente fornito non era errata, solo migliorabile (e in un progetto regolare la differenza sarebbe piuttosto piccola). –

2

std::complex<T> Gli operatori sono definiti per prendere come argomenti altre istanze complex<T>. Il percorso da uno a complex<double> è leggermente troppo contorto/convoluto per il linguaggio C++ per seguirlo secondo lo standard (e con le enormi complicazioni già derivanti dalle conversioni e dalle coerenze a ruota libera è difficile criticare lo che aspetto dello standard). Immagino che il caso super-speciale di complex<double> che consente gli int s non trasmessi come operandi ai suoi operatori non sia stato ritenuto abbastanza frequente e importante da giustificare la specificazione dei modelli per quel caso estremamente individuale, considerando quanto sia facile per il programmatore trasmettere il int a double quando questo è quello che in realtà vogliono -!)

+0

-1: lo standard fornisce funzioni libere simmetriche per moltiplicare un complesso std :: da T. (C++ 03, 26.2.6 [lib.complex.ops] Operazioni non associate complesse) –

Problemi correlati