用空的初始值设定项列表调用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()
迭代器的取消引用。
那么,这段代码在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需要:
T
是LessThanComparable
和CopyConstructible
以及t.size() > 0
。
(强调矿)
C++11中也有同样的措辞。