La chiamata a std::min()
con un elenco di inizializzazione vuoto di solito non viene compilata (tutta la domanda può essere dichiarata allo stesso modo per std::max()
). Questo codice:Sta chiamando std :: min su un elenco inizializzatore vuoto (e specificando esplicitamente il tipo) comportamento non definito?
#include <iostream>
#include <algorithm>
int main() {
std::cout << std::min({}) << "\n";
return 0;
}
Con clangore dà questo errore:
test.cpp:6:17: error: no matching function for call to 'min'
std::cout << std::min({}) << "\n";
^~~~~~~~
algorithm:2599:1: note:
candidate template ignored: couldn't infer template argument '_Tp'
min(initializer_list<_Tp> __t)
Posso capire perché questo caso non sarebbe stato permesso, perché è difficile essere d'accordo su un valore ragionevole di tornare in questo caso .
Tuttavia, tecnicamente parlando il codice non viene compilato solo perché non è possibile dedurre il parametro del modello. Se forzo il parametro il codice viene compilato ma ottengo un incidente:
#include <iostream>
#include <algorithm>
int main() {
std::cout << std::min<int>({}) << "\n";
return 0;
}
$ clang++ -std=c++11 test.cpp -o test
$ ./test
Segmentation fault: 11
Sembra che l'incidente si pone perché std::min()
è implementato in termini di std::min_element()
, ed una lista di inizializzazione vuota risultati nella dereference di un invalido end()
iteratore.
Quindi questo comportamento del codice è indefinito in C++ 11/C++ 14? È std::min()
dichiarato di non essere compilato quando chiamato senza parametri template espliciti? È stato specificato std::min()
da implementare in termini di std::min_element()
?
Non mi aspettavo che facesse qualcosa in particolare. – gigabytes
Sono d'accordo non c'è una buona risposta, in linea di principio. Lo dico anche nella domanda. Ma dal momento che un modo di invocarlo si compila e un altro no, ho chiesto se quello che compila fosse effettivamente specificato come UB. – gigabytes