正在对空的初始值设定项列表调用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)
我明白为什么这种情况不被允许,因为在这种情况下很难就合理的回报价值达成一致。
然而,从技术上讲,代码并不只是因为模板参数无法推导而编译的。如果我强制参数,代码会编译,但我会崩溃:
#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中也有同样的措辞。
相关文章:
- ArduinoJson 6.15.2:JsonObject没有命名类型
- 防止主数据类型C++的隐式转换
- 大量序列中核苷酸类型的快速计数
- 如何从C++中的依赖类型中获得它所依赖的类型
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如何获取std::result_of函数的返回类型
- 从父命名空间重载类型
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 访问者访问变体并返回不同类型时出错
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- STD :: Min of std :: Chrono ::不同类型的持续时间
- std::min/max类型扣除在Linux和Windows上不同
- std::min未能将枚举常量解释为有效的整数类型(g++4.6.3)
- 为什么小于操作符接受不同类型的参数,而std::min不接受
- 如何在可变参数包中找到"min"类型?
- 正在对空的初始值设定项列表调用std::min(并显式指定类型)未定义的行为