Вызывается std:: min в пустом списке инициализаторов (и явно указывается тип) undefined поведение?
Вызов std::min()
с пустым списком инициализаторов обычно не компилируется (все вопросы могут быть указаны одинаково для std::max()
).
Этот код:
#include <iostream>
#include <algorithm>
int main() {
std::cout << std::min({}) << "\n";
return 0;
}
С помощью clang эта ошибка:
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)
Я понимаю, почему этот случай не будет разрешен, потому что в этом случае трудно согласиться на разумную ценность.
Однако, с технической точки зрения, код не компилируется только потому, что параметр шаблона не может быть выведен. Если я заставляю параметр компилировать код, но я получаю сбой:
#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
Кажется, что сбой возникает, потому что std::min()
реализуется в терминах std::min_element()
, а пустой список инициализаторов приводит к разыменованию недействительного итератора end()
.
Итак, это часть кода undefined поведение в С++ 11/С++ 14?
Утверждается ли std::min()
не компилировать при вызове без явных параметров шаблона?
Является ли std::min()
указанным для реализации в терминах std::min_element()
?
Ответы
Ответ 1
Да, это UB. Согласно С++ 14 (n4140) 25.4.7/4:
template <class T>
constexpr T min(initializer_list<T> t);
...
4 Требуется: T
- LessThanComparable
и CopyConstructible
и t.size() > 0
.
(Акцент мой)
Такая же формулировка присутствует и в С++ 11.