Perché std :: min supporta solo initializer_list?
Possiamo usare std::minnel modo seguente:
// 1.
int a = 1, b = 2;
std::min(a, b);
// 2.
std::min({1,2,3,4});
Ma perché non è possibile utilizzare un std::vectoro std::list, perché il parametro nel modello è initializer_list.
template <class T, class Compare>
pair<T,T> minmax (initializer_list<T> il, Compare comp);
Qual è il motivo di questo design?
Risposte
Per spiegare "perché non accetta un contenitore", prendi in considerazione la semantica:
std::min({ "foo", "bar", "hello" })
La semantica di std::min()significa "trova il valore minimo nei parametri di input". Quindi std::min()/ std::max()accetta due argomenti o un initializer_list come "più argomenti".
std::min() non fornisce la possibilità di "iterare attraverso un contenitore", perché un contenitore è considerato come "un parametro".
Per trovare il valore minimo in un contenitore, c'è std::min_element(), e il suggerimento di eerorika std::ranges::min()in C ++ 20 dovrebbe essere migliore.
Per l' std::min_element()utilizzo, puoi fare riferimento a Come posso ottenere il valore massimo (o minimo) in un vettore? .
"Più pensano troppo all'impianto idraulico, più è facile chiudere lo scarico". - Comandante Montgomery Scott
Lo scopo di std::minè restituire il più piccolo dei suoi parametri. Semplice e succinto. Come con i tuoi progetti, è meglio che una funzione (o un modello di funzione) faccia bene una cosa piuttosto che molte cose male. Pertanto, std::minnon ha alcuna conoscenza dei contenitori. Sa semplicemente come prendere due cose e confrontarle. La conoscenza dei contenitori è stata invece concessa a std::min_element. Tra i due modelli, è stata coperta la maggior parte dei casi d'uso.
Un caso che non è stato coperto è stato quello di trovare il minimo di più di due elementi quando quegli elementi non erano gli elementi di un (intervallo all'interno di un) contenitore. Questo caso potrebbe essere gestito dal collegamento a margherita std::min, ma è alquanto scomodo farlo. Per C ++ 11, è stato deciso che i vantaggi della gestione di più parametri superavano il costo di complicare il modello, purché le complicazioni fossero ridotte al minimo. Così è stato scelto un unico, semplice meccanismo per fornire un numero arbitrario di argomenti, vale a dire std::initializer_list. Non è necessario consentire contenitori arbitrari perché std::min_elementcopre già quella situazione.
Ma perché non è possibile utilizzare std :: vector o std :: list, perché il parametro nel modello è initializer_list.
Perché non esiste un sovraccarico che accetti un vettore o un elenco. Quelli non sono elenchi di inizializzatori.
Dal momento che C ++ 20 puoi usare std::ranges::minin cui puoi passare uno di quei contenitori o addirittura qualsiasi intervallo. Prima di questo, c'è std::min_elementche funziona con qualsiasi coppia di iteratori.