Why does std::min only support initializer_list?

允我心安 提交于 2021-01-20 09:16:04

问题


We can use std::min in below way:

// 1.
int a = 1, b = 2;
std::min(a, b);

// 2.
std::min({1,2,3,4});

But why can't use a std::vector or std::list, Because the param in the template is initializer_list.

template <class T, class Compare>
  pair<T,T> minmax (initializer_list<T> il, Compare comp);

What is the reason for this design?


回答1:


To explain "why it doesn't accept a container", take the semantic into consideration:

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

The semantic of std::min() means "find the minimum value in the input parameters". Thus std::min()/std::max() takes two arguments, or an initializer_list as "more arguments".

std::min() doesn't provide the ability to "iterate through a container", because a container is considered as "a parameter".

To find the min value in a container, there is std::min_element(), and eerorika's suggestion std::ranges::min() in C++20 should be better.

For std::min_element() usage, you may refer to How can I get the max (or min) value in a vector?.




回答2:


"The more they overthink the plumbing, the easier it is to stop up the drain." – Commander Montgomery Scott

The purpose of std::min is to return the smaller of its parameters. Simple and succinct. As with your own designs, it is better for a function (or function template) to do one thing well than to do many things poorly. Thus, std::min has no knowledge of containers. It simply knows how to take two things and compare them. Knowledge of containers was instead granted to std::min_element. Between the two templates, most use cases were covered.

One case that was not covered was finding the minimum of more than two elements when those elements were not the elements of a (range within a) container. This case could be handled by daisy-chaining std::min, but it is somewhat awkward to do so. For C++11, it was decided that the benefits of handling more parameters outweighed the cost of complicating the template, as long as the complications were kept to a minimum. Thus a single, simple mechanism for supplying an arbitrary number of arguments was chosen, namely std::initializer_list. There is no need to allow arbitrary containers because std::min_element already covers that situation.




回答3:


But why can't use a std::vector or std::list, Because the param in the template is initializer_list.

Because there is no overload that would accept a vector or a list. Those are not initialiser lists.

Since C++20 you can use std::ranges::min into which you can pass either of those containers or indeed any range. Prior to that, there is std::min_element which works with any pair of iterators.



来源:https://stackoverflow.com/questions/64056886/why-does-stdmin-only-support-initializer-list

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!