为什么 std::min 只支持 initializer_list?
Why does std::min only support initializer_list?
我们可以通过以下方式使用std::min
:
// 1.
int a = 1, b = 2;
std::min(a, b);
// 2.
std::min({1,2,3,4});
但是为什么不能使用std::vector
或std::list
,因为模板中的参数是initializer_list
的。
template <class T, class Compare>
pair<T,T> minmax (initializer_list<T> il, Compare comp);
这种设计的原因是什么?
要解释"为什么它不接受容器",请考虑语义:
std::min({ "foo", "bar", "hello" })
std::min()
的语义意味着"在输入参数中找到最小值"。因此,std::min()
/std::max()
需要两个参数,或者一个initializer_list作为"更多参数"。
std::min()
不提供"循环访问容器"的功能,因为容器被视为"参数"。
要找到容器中的最小值,有std::min_element()
,eerorika的建议std::ranges::min()
在C++20中应该更好。
对于std::min_element()
用法,您可以参考如何获取向量中的最大值(或最小值)?。
"他们对管道越想得太多,就越容易堵塞排水管。">
std::min
的目的是返回其较小的参数。简单简洁。与您自己的设计一样,函数(或函数模板)做好一件事比做很多事情做得不好要好。因此,std::min
对容器一无所知。它只是知道如何拿两件事并进行比较。相反,容器的知识被授予std::min_element
。在这两个模板之间,涵盖了大多数用例。
未涵盖的一种情况是,当这些要素不是(在一个容器内的范围)的要素时,找到至少两个以上要素。这种情况可以通过菊花链std::min
来处理,但这样做有点尴尬。对于C++11,决定处理更多参数的好处超过了使模板复杂化的成本,只要将复杂性保持在最低限度。因此,选择了一种单一的、简单的机制来提供任意数量的参数,即std::initializer_list
。没有必要允许任意容器,因为std::min_element
已经涵盖了这种情况。
为什么不能使用std::vector或std::list,因为模板中的参数是initializer_list的。
因为没有接受向量或列表的重载。这些不是初始化器列表。
从 C++20 开始,您可以使用std::ranges::min
,您可以将这些容器中的任何一个或任何范围传递到其中。在此之前,有std::min_element
适用于任何一对迭代器。
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 如何在 C 中正确使用 libiconv 使其不会报告"Arg list too long"?
- C++中带有List类的迭代器Segfault
- 使用"std::unordereded_map"映射到"std::list"对象
- GCC对可能有效的代码抛出init list生存期警告
- 使用std::list创建循环链表
- C2664 无法从'initializer list'转换参数
- 使用 std::min "no matching function for call to ‘min(<brace-enclosed initializer list>)’"时出错
- 在C++中标记化"Braced Initializer List"样式字符串(使用 Boost?
- "默认参数":无法从'initializer list'转换为'std::initializer_list'
- 无法从'initializer-list'转换为用户控制器
- 如何修复<function-style-cast>错误:无法从'initializer list'转换为asdending比较<W>(模板函子)
- 递归调用中出现错误"[Error] expression list treated as compound expression in initializer [-fpermissive]"
- VS2015无法从'initializer list'转换为'std::string'错误
- 编译器错误:"Non-aggregates cannot be initialized with initializer list."
- 无法转换...从 '<brace-enclosed initializer list>' 到 地图
- 无法将'<brace-enclosed initializer list>'转换为'double'作为回报
- <function-style-cast> 错误:无法从'initializer list'转换为'std::thread'
- initializer语言 - list不能转换为const margin *