我们可以通过以下方式使用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
适用于任何一对迭代器。