2015-06-05 11 views
7

dieses Stück Code vor:Hinzufügen von Doppel- und komplexen Zahlen in C++

#include <iostream> 
#include <complex> 

int main() 
{ 
    std::complex<double> z1 = 5; 
    std::cout << z1 - 1 << "\n"; // must change to z1 - 1.0 to compile 

    std::complex<int> z2 = 5; 
    std::cout << z2 - 1.0 << "\n"; // must change to z2 - 1 to compile 
} 

Dies erzeugt einen Übersetzungsfehler, da keine operator- für die Typen in der Ausdrücken z1 - 1 oder z2 - 1.0 gefunden wird. Auf der anderen Seite funktioniert es gut, diese Ausdrücke so zu ändern, dass die Basistypen übereinstimmen.

Naiv für z1 - 1 würde ich die int 1 erwarten zu einem double gefördert werden, und erwartete, dass die z2, mit dem Basistyp int, in z2 - 1.0 zu einem complex<double> gefördert werden. Was ist los?

Antwort

6

Die operator-, die Sie aufrufen möchten, ist eine Funktionsvorlage mit einem einzigen Typvorlagenparameter.

template< class T > 
complex<T> operator-(const complex<T>& lhs, const T& rhs); 

Keine der Template-Parameter in den beiden Funktionsparametern erscheint in einem nicht abgeleiteten Zusammenhang so Template-Argument Abzug wird individuell auf beiden Parametern durchgeführt, und dies führt zu den T für lhs als double abgeleitet wurde, während das für rhs wird als int abgeleitet.

Aufgrund dieser Diskrepanz zwischen den abgeleiteten Typen schlägt das Ableiten des Vorlagenarguments fehl, und Ihr Code wird nicht kompiliert.

+1

Normalerweise verwende ich 'std :: identity :: type', um die Deduktion für nachfolgende Parameter zu unterdrücken, ich finde, dass es viel besser für Fälle sehr ähnlich wie dieser funktioniert. Ich frage mich, warum sie das nicht im Standard gemacht haben? Vielleicht würden sie es als einen Defekt betrachten, aber es könnte einen tieferen Grund geben, warum sie es nicht so gemacht haben. – VoidStar

+0

@VoidStar Nicht sicher, was die Geschichte ist, aber "komplex" gibt es schon seit C++ 98, also könnte es einfach sein, dass damals noch niemand daran gedacht hat. Interessanterweise gibt es eine [Converting Constructor Template] (http://en.cppreference.com/w/cpp/numeric/complex/complex) Definition, also würden Sie denken, dass 'operator-' mit 2 definiert wäre verschiedene Template-Parameter auch. – Praetorian

0

Der Compiler konvertiert Typen nicht automatisch von A nach B in C, wenn A ein Integral und B ein Fließkommawert ist. Sie möchten, dass der Compiler von int ->double ->complex<double> konvertiert, aber das wird es nicht tun.

Für das zweite Beispiel müssten Sie die complex<int> zu einer complex<double>, die nicht automatisch von der Klassenvorlage complex behandelt wird.

Verwandte Themen