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

gig*_*tes 15 c++ undefined-behavior stl-algorithm c++11 c++14

std::min()使用空的初始化列表调用通常不会编译(所有问题都可以用相同的方式表示std::max()).这段代码:

#include <iostream>
#include <algorithm>

int main() {
   std::cout << std::min({}) << "\n";
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用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)
Run Code Online (Sandbox Code Playgroud)

我可以看出为什么不允许这种情况,因为在这种情况下难以就回归的合理价值达成一致.

但是,从技术上讲,代码不能编译,因为无法推导出模板参数.如果我强制参数代码编译但我崩溃了:

#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
Run Code Online (Sandbox Code Playgroud)

似乎崩溃是因为std::min()实现了崩溃std::min_element(),并且空的初始化列表导致无效end()迭代器的解除引用.

那么这段代码在C++ 11/C++ 14下的未定义行为是什么?是std::min()说,当没有明确的模板参数调用不能编译?是否std::min()指定实施std::min_element()

Rei*_*ica 22

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

template <class T>
constexpr T min(initializer_list<T> t);
Run Code Online (Sandbox Code Playgroud)

...

4 要求: TLessThanComparableCopyConstructiblet.size() > 0.

(强调我的)

C++ 11中也有相同的措辞.