2009-10-29 5 views
8

C++ programuDlaczego jest złożona <double> * int nie zdefiniowane w C++?

#include <complex> 
#include <iostream> 

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

daje błąd: nie pasuje do operatora „*” w „oo * n”. Czemu?

Kompiluję się z g ++ 4.4.1. Być może kompilator jest zgodny ze standardem C++, w którym to przypadku moje pytanie brzmi: dlaczego standard nie pozwala na to?

Odpowiedz

14

to działa:

#include <complex> 
#include <iostream> 

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

Ponieważ kompleks składa się z podwójnej, to mnoży się podwaja. Patrząc na deklaracji:

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

(Poniżej dzięki dribeas) Kompilator nie jest dozwolone, aby niejawne konwersje typów podczas szablonu dedukcji, więc przez przepuszczenie complex z T będąc double, a potem jeszcze T będąc , próbując dopasować funkcję traktując T jako double powoduje, że drugi argument źle pasuje, i na odwrót.

Do czego chcesz pracować, to mieć funkcja zdefiniowana podobny do tego:

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

który umożliwia funkcja do podjęcia różnych typów, co pozwala obsady do zrobienia podczas wywoływania operator*=.

+0

myślę jego ponieważ kompleks jest klasa, a * jest przeciążony dla tej klasy, to nie prymitywny tak nie wynika odlewania zasady w kompilator – ldog

+0

Dzięki Poprawiłem błąd związany z niejednoznacznością i błędem prawidłowego zakodowania operatora. (Powinienem zrobić drugi, ale pierwszy jest dla mnie lekcją.) – GManNickG

+0

Implementacja operatora, który pierwotnie dostarczyłeś, nie była niepoprawna, tylko poprawna (a przy zwykłym projekcie różnica byłaby raczej mała). –

2

std::complex<T> Operatory są zdefiniowane jako przyjmujące jako swoje argumenty inne instancje complex<T>. Trasa od int poprzez double do jest tylko nieznacznie zbyt wykrzywiona/zawiłowana, aby język C++ mógł ją śledzić zgodnie ze standardem (i z ogromnymi komplikacjami wynikającymi już z konwersji i kołowrotów swobodnych trudno jest krytykować , że aspekt standardu). Przypuszczam, że wyjątkowy przypadek complex<double> zezwalający na nieprzemyślane int s jako operandów do jego operatorów nie był po prostu uważany za częsty i wystarczająco ważny, aby uzasadnić określenie specjalizacji szablonu dla tego wyjątkowo indywidualnego przypadku, biorąc pod uwagę, jak trywialnie łatwo jest programistce rzucić int do double kiedy to właśnie oni faktycznie chcą -!)

+0

-1: Standard zapewnia symetryczne, bezpłatne funkcje do pomnożenia std :: complex przez T. (C++ 03, 26.2.6 [lib.complex.ops] Złożone operacje nie będące elementami) –