在一个空的初始化列表(并明确指定类型)上调用 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 中也存在相同的措辞。
用一个空的初始化列表调用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
isLessThanComparable
andCopyConstructible
andt.size() > 0
.
(强调我的)
C++11 中也存在相同的措辞。