在一个空的初始化列表(并明确指定类型)上调用 std::min 是未定义的行为吗?

Is calling std::min on an empty initializer list (and explicitly specifying the type) undefined behavior?

用一个空的初始化列表调用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)

我明白为什么不允许这种情况,因为在这种情况下很难就 return 的合理值达成一致。

但是,从技术上讲,代码无法编译只是因为无法推导模板参数。如果我强制参数代码编译但我得到一个崩溃:

#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() 迭代器的取消引用。

那么这段代码在C++11/C++14下是未定义行为吗? std::min() 是否声明在没有显式模板参数的情况下调用时不编译? std::min()是否指定按std::min_element()执行?

是的,是 UB。根据 C++14 (n4140) 25.4.7/4:

template <class T>
constexpr T min(initializer_list<T> t);

...

4 Requires: T is LessThanComparable and CopyConstructible and t.size() > 0.

(强调我的)

C++11 中也存在相同的措辞。