2012-09-07 7 views
23

stavo guardando la classe std::ratio<> dallo standard C++ 11 che permette di fare in fase di compilazione aritmetica razionale.Principi di progettazione dietro std :: rapporto <>

ho trovato il modello di progettazione e le operazioni poste in essere con le classi eccessivamente complessi e non ha trovato alcun motivo per cui non potrebbe utilizzare un approccio più semplice e intuitivo mediante l'attuazione di una realtà semplice classe razionale e definendo constexpr funzioni per gli operatori. Il risultato sarebbe stato una classe più facile da usare e i vantaggi in fase di compilazione sarebbero rimasti.

Qualcuno ha qualche idea dei vantaggi dell'attuale design std::ratio<> rispetto a un'implementazione di classe semplice utilizzando constexpr? In realtà, non riesco a trovare alcun vantaggio all'attuale implementazione.

+4

http://www.joelonsoftware.com/articles/fog0000000018.html –

+0

Non è forse compilare in tempo (quindi modelli) vs runtime? – Drakosha

+4

@Drakosha: 'constexpr' non è un suggerimento; in determinati contesti (dove è richiesta un'espressione costante), un compilatore * deve * eseguirli in fase di compilazione. –

risposta

36

Quando è stato proposto N2661, nessuno degli autori della proposta ha avuto accesso a un compilatore che ha implementato constexpr. E nessuno di noi era disposto a proporre qualcosa che non avremmo potuto costruire e testare. Quindi, se un progetto migliore avrebbe potuto essere fatto con constexpr non era nemmeno parte della considerazione per il design. Il progetto era basato solo su quegli strumenti disponibili per gli autori al momento.

+0

Ovviamente verrai con una risposta così pratica. : -] – ildjarn

+4

@ jon34yp: interessante il fatto che l'interrogante abbia posto due domande: (1) quali erano i principi di progettazione alla base di 'std :: ratio', su quale argomento penso che Howard sia un'autorità. (2) quali sono i vantaggi del design attuale, che potrebbero avere ogni sorta di risposta di cui Howard è inconsapevole, non averlo mai preso in considerazione :-) –

0

std::ratio ei suoi meccanismi circostanti sarà sempre eseguito al momento della compilazione, in virtù di template metaprogrammazione e tipo di manipolazione. constexpr è richiesto solo per l'esecuzione in fase di esecuzione quando è richiesta un'espressione costante dalle strutture C++ (come i parametri di un modello o l'inizializzazione di una variabile constexpr).

Così che è più importante per voi: l'esecuzione in fase di compilazione, o di essere "più semplice e intuitivo"?

+3

Con 'constexpr', possiamo avere sia l'uso intuitivo che l'esecuzione in fase di compilazione per espressioni costanti, quindi con le stesse identiche espressioni dei modelli. Quindi entrambi i vantaggi in una sola volta sembrano piuttosto un commercio equo. – Morwenn

+2

@Morwenn: Il punto di Nicol sta cercando di fare è che se si utilizza un 'constexpr' in una situazione in cui non è richiesta (per esempio un'espressione regolare all'interno di una funzione) il' constexpr' può o non può essere valutata in fase di compilazione, cioè potrebbe attivare una chiamata di funzione in fase di esecuzione. Si noti inoltre che le funzioni 'constexpr' possono usare solo un sottoinsieme della lingua, quindi potrebbero non produrre comunque un disegno così naturale. –

+3

@David: puoi forzare una funzione 'constexpr' in qualche altro contesto per essere valutata in fase di compilazione, usando trucchi come' template struct compile_time_dammit {enum {value = N}; }; ... compile_time_dammit :: value; '. Tutto ciò è discutibile dal momento che la risposta alla domanda non ha nulla a che fare con i pro ei contro di 'constexpr' :-) –

13

La soluzione constexpr risolve problema completamente diverso. std::ratio è stato creato per essere usato come un ponte tra le variabili che usano unità diverse, non come uno strumento matematico. In queste circostanze, è assolutamente necessario che il rapporto faccia parte del tipo. La soluzione di constexpr non funzionerà qui. Ad esempio, non sarà possibile implementare std::duration senza uno spazio di runtime e costi di runtime, poiché ogni oggetto di durata dovrebbe portare le informazioni del suo nominatore/denominatore all'interno dell'oggetto.

+0

Idem per una ragionevole libreria dove si vorrebbe poteri frazionari delle varie dimensioni ma a) non vorresti portare in giro tre o cinque frazioni effettive eb) vorresti che dist + time sia un errore del tipo di compilatore non un errore di runtime. – emsr