2012-06-19 16 views
35

Secondo le specifiche ISO C++, § 26,2/2:Perché C++ richiede che il complesso venga istanziato solo per float, double o long double?

L'effetto di istanziare modello complex per qualsiasi tipo diverso da float, double o long double è specificato.

Perché gli autori standard aggiungono esplicitamente questa restrizione? Ciò lo rende non specificato, ad esempio, cosa succede se si effettua complex<int> o complex<MyCustomFixedPointType> e sembra una restrizione artificiale.

C'è una ragione per questa limitazione? C'è una soluzione alternativa se vuoi istanziare complex con il tuo tipo personalizzato?

Sto principalmente chiedendo questa domanda a causa di this earlier question, in cui l'OP era confuso sul motivo per cui abs stava dando uscite bizzarre per complex<int>. Detto questo, questo non ha ancora senso dato che potremmo anche voler fare numeri complex di tipi a punti fissi, numeri reali con maggiore precisione, ecc.

+4

Ho dovuto ridere dopo aver visto la tua risposta precedente, ma è davvero una buona domanda. – chris

+9

@ chris- Mi sentivo male a dare quella risposta senza essere in grado di dare una ragione di alto livello per questo. Di solito sono bravo a dire "questo è un caso bizzarro di C++ per i motivi X, Y e Z", ma questa volta non ho idea di cosa succede. – templatetypedef

+4

"Il complesso di standardizzazione è stato discusso ininterrottamente nel comitato per oltre un decennio e esiste una resistenza significativa da parte di almeno un fornitore per supportarlo." http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-March/020398.html –

risposta

28

Non è possibile implementare correttamente molte delle operazioni std::complex su numeri interi. Per esempio,

template <class T> 
T abs(const complex<T> &z); 

per un complex<long> non può avere T = long valore di ritorno quando i numeri complessi sono rappresentati come coppie (real, imag), dal momento che restituisce il valore di sqrt(pow(z.real(), 2) + pow(z.imag(), 2)). Solo alcune delle operazioni avrebbero senso.

Ancor peggio, il costruttore con nome polar non può essere reso affidabile senza interrompere il costruttore predefinito e viceversa. Lo standard dovrebbe specificare che "interi complessi" sono Gaussian integers perché possano essere utili e che uno dei costruttori sia gravemente danneggiato.

Infine, come ti piacerebbe la tua "divisione di interi complessi", e ti piacerebbe un "resto complesso" con quello? :)

Riassumendo, penso che sarebbe più ragionevole per specificare un gaussian_int<T> tipo separato con poche operazioni di supporto per innesto solidale T su std::complex.

+1

Strano come abbiamo scelto la stessa identica funzione per illustrare. :) –

+0

Grazie per aver introdotto una solida motivazione matematica per la decisione. Penso che questo fornisca un elegante motivo teorico per la decisione. Non avevo mai sentito parlare degli interi Gaussiani, quindi grazie per averli mostrati! – templatetypedef

+0

@templatetypedef: Grazie e +1 per la domanda. Non avevo mai considerato cosa sarebbe successo quando 'complex' era basato su tipi interi. [Non sono un matematico, però, e se qualcuno può dimostrarmi in errore, per favore.] –

12

Probabilmente per la compatibilità con le funzioni di supporto. Per esempio:

template<class T> T abs (const complex<T>& x); 

Se T == int, abs sarebbero tornati int, il che significherebbe una massiccia perdita di precisione.

Problemi correlati