为什么 std::min 只支持 initializer_list?

Why does std::min only support initializer_list?

本文关键字:list initializer std min 为什么 支持      更新时间:2024-04-28

我们可以通过以下方式使用std::min

// 1.
int a = 1, b = 2;
std::min(a, b);
// 2.
std::min({1,2,3,4});

但是为什么不能使用std::vectorstd::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适用于任何一对迭代器。