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

时间:2020-09-25 02:21:54

标签: c++ std

我们可以通过以下方式使用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);

这种设计的原因是什么?

3 个答案:

答案 0 :(得分:3)

但是为什么不能使用std :: vector或std :: list,因为模板中的参数是initializer_list。

因为没有重载会接受向量或列表。这些不是初始化程序列表。

从C ++ 20开始,您可以使用std::ranges::min,您可以将这些容器或实际上是任何范围的容器传递到其中。在此之前,std::min_element与任何一对迭代器一起使用。

答案 1 :(得分:3)

要解释“为什么它不接受容器”,请考虑以下语义:

std::min({ "foo", "bar", "hello" })

std::min()的语义意思是“在输入参数中找到最小值”。因此std::min() / std::max()接受两个参数,或者将initializer_list用作“更多参数”。

std::min()不提供“通过容器迭代”的功能,因为容器被视为“参数”。

要找到容器中的最小值,请使用std::min_element(),C ++ 20中eerorika的建议std::ranges::min()应该更好。

对于std::min_element()的用法,您可以参考How can I get the max (or min) value in a vector?

答案 2 :(得分:3)

“他们对水管的考虑越多,堵塞排水口就越容易。” –蒙哥马利·斯科特司令官

std::min的目的是返回较小的参数。简单而简洁。与您自己的设计一样,对于功能(或功能模板)而言,做好一件事情总比做好许多事情要好。因此,std::min不了解容器。它只是知道如何拿两件事并进行比较。相反,将容器知识授予了std::min_element。在这两个模板之间,涵盖了大多数用例。

一个未被涵盖的案例是,当那些元素不是容器(在a内)的元素时,找到两个以上的最小值。可以通过菊花链std::min处理这种情况,但是这样做有些尴尬。对于C ++ 11,可以确定的是,只要将复杂性保持在最低程度,处理更多参数的好处就超过了使模板复杂化的代价。因此,选择了一种用于提供任意数量参数的简单机制,即std::initializer_list。无需允许使用任意容器,因为std::min_element已经涵盖了这种情况。