2013-05-11 13 views
8

Scrivendo una funzione minima generale, mi sono venute in mente due domande. Il codice funziona bene con qualsiasi tipo di ingresso e il numero di argomento diverso:Generale min e max - C++

namespace xyz 
{ 

template <typename T1, typename T2> 
auto min(const T1 &a, const T2 &b) -> decltype(a+b) 
{ 
    return a < b ? a : b; 
} 

template <typename T1, typename T2, typename ... Args> 
auto min(const T1 &a, const T2 &b, Args ... args) -> decltype(a+b) 
{ 
    return min(min(a, b), args...); 
} 

} 

int main() 
{ 
    cout << xyz::min(4, 5.8f, 3, 1.8, 3, 1.1, 9) << endl; 
    //     ^ ^  ^
    //     |  |   | 
    //     float double  int 
} 

 

  • Esiste un sostituto migliore per decltype(a+b)? Io cosa c'è una classe standard che non riesco a ricordare, qualcosa come decltype(std::THE_RESULT<a,b>::type).

  • Il tipo restituito di quello decltype(std::THE_RESULT<a,b>::type) è const & oppure no?

+1

Sembra strano a me che si consente a e b per essere diversi tipi. Questo apre la porta a tutti i tipi di confronti privi di senso, come 'min (42," three ")'. Perché non richiedere che entrambi i parametri (e il valore restituito) siano tutti dello stesso tipo? –

+1

@AdrianMcCarthy: _ "Per i tipi aritmetici, il tipo comune può anche essere visualizzato come il tipo di un'espressione aritmetica (possibilmente in modalità mista) come T0() + T1() + ... + Tn()" _. Quindi penso che sia proibito usare 'min (42," three ")'. Rende l'errore di compilazione. – deepmax

+0

A proposito, c'è un articolo sulla riproduzione delle parti buone delle versioni macro usando i template. È sorprendentemente molto da fare. – chris

risposta

13

std::common_type (c++11):

Per non specializzati std::common_type, le regole per determinare il tipo corrente tra ogni coppia T1, T2 sono esattamente le regole per determinano il tipo di ritorno del operatore condizionale ternario dove T1 e T2 sono i tipi del relativo secondo e terzo operando.

e

Per i tipi aritmetici, il tipo comune può anche essere considerato come il tipo del (possibilmente modalità mista) espressione aritmetica come T0() + T1() + ... + Tn().

Non sono sicuro const&, ma potresti giocare con std::remove_cv e std::remove_reference (e std::is_reference per trovare la risposta).

Infatti, here's un elenco di utilità di supporto del tipo. Staccati.

+0

Grazie ... Ho aggiunto una terza domanda correlata. Ti dispiacerebbe dargli un'occhiata? – deepmax

+2

@MM.Funzionerà ma non è completamente ciò che vuoi, penso. Per '(1,2,1.1)' che restituirà un 'int'. 'decltype (min (1, 2))'. Puoi provare a coprire l'intera cosa come 'decltype (min (min (a, b), args ...))' ma questo non funziona con 'gcc' adesso. Penso che sia un bug. – stardust

+0

@Named: Sì, l'ho provato e hai ragione. – deepmax

5

Dopo i commenti di risposta e del valore che ho fatto come qui sotto:

template <typename T1, typename T2> 
auto min(const T1 &a, const T2 &b) 
-> typename std::common_type<const T1&, const T2&>::type 
{ 
    return a < b ? a : b; 
} 

template <typename T1, typename T2, typename ... Args> 
auto min(const T1 &a, const T2 &b, const Args& ... args) 
-> typename std::common_type<const T1&, const T2&, const Args& ...>::type 
{ 
    return min(min(a, b), args...); 
}