Вызывается 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.