min, max, minmax for std::pair

100 views
Skip to first unread message

Vlad from Moscow

unread,
Dec 9, 2017, 9:29:34 AM12/9/17
to ISO C++ Standard - Future Proposals
What about introducing algorithms min, max, and minmax for the template class std::pair?

r. For example

 template <typename T>
 constexpr const T & min(const std::pair<T, T> &p)
 {
  return p.second < p.first ? p.second : p.first;
 }

Michał Dominiak

unread,
Dec 9, 2017, 10:25:30 AM12/9/17
to std-pr...@isocpp.org

Why?


--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/132ff725-5463-4d9c-a291-3314a56dca50%40isocpp.org.

Vlad from Moscow

unread,
Dec 11, 2017, 9:09:00 AM12/11/17
to ISO C++ Standard - Future Proposals
Why not?

суббота, 9 декабря 2017 г., 18:25:30 UTC+3 пользователь Michał Dominiak написал:

Michał Dominiak

unread,
Dec 11, 2017, 9:19:23 AM12/11/17
to std-pr...@isocpp.org
That's not how it works. You are supposed to present rationale, otherwise no-one will care about your paper, because without solving an actual problem, it'll be just a huge waste of time.

Vlad from Moscow

unread,
Dec 11, 2017, 9:31:55 AM12/11/17
to ISO C++ Standard - Future Proposals
I am not discussing "how it works". I want to collect opinions about introducing these functions.

понедельник, 11 декабря 2017 г., 17:19:23 UTC+3 пользователь Michał Dominiak написал:

Jake Arkinstall

unread,
Dec 11, 2017, 9:43:22 AM12/11/17
to std-pr...@isocpp.org

Why not?

I can think of a few reasons.

Firstly, because it doesn't make much sense from a semantics perspective. The first and second properties of a pair (just like the elements of a tuple) are not really intended to be compared with one another - they are wholly separate entities related only by some previous action (e.g. a map from one to the other, or as multiple return values of a function), and the two having the comparable type is rare.

If they ARE meant to be compared and are the same type, you should probably be using a std::array. If they are two different types with some defined comparison operation, you're looking at an edge case for which custom code is probably suitable (especially as you'd probably want to document it properly).

Secondly, getting the min and max of a pair is trivial. You can write min(p.first, p.second) with minimal effort, and is very readable. In fact, I would consider it considerably more readable than min(p).

Vlad from Moscow

unread,
Dec 11, 2017, 10:11:59 AM12/11/17
to ISO C++ Standard - Future Proposals


понедельник, 11 декабря 2017 г., 17:43:22 UTC+3 пользователь Jake Arkinstall написал:

Why not?

I can think of a few reasons.

Firstly, because it doesn't make much sense from a semantics perspective. The first and second properties of a pair (just like the elements of a tuple) are not really intended to be compared with one another - they are wholly separate entities related only by some previous action (e.g. a map from one to the other, or as multiple return values of a function), and the two having the comparable type is rare.


I can not agree with this statement.. If elements of a pair have the same type then max and min can be considered as properties of the pair.

Consider the following demonstrative program.

#include <iostream>
#include <utility>
#include <algorithm>
#include <iterator>
namespace usr
{

 template <typename T>
 constexpr const T & min(const std::pair<T, T> &p)
 {
  return std::min( p.first, p.second );
 }
 template <typename T>
 constexpr const T & max(const std::pair<T, T> &p)
 {
  return std::max(p.first, p.second);
 }
}
int main()
{
 std::pair<int, int> arr[] =
 {
  { 4, 10 }, { 7, 6 }, { 3, 8 }, { 9, 1 }
 };

 for (const auto &p : arr)
 {
  std::cout << p.first << ", " << p.second << '\n';
 }
 std::cout << std::endl;
 std::sort(std::begin(arr), std::end(arr),
  [](const auto &p1, const auto &p2)
  {
   return usr::max(p1) < usr::max(p2);
  });
 for (const auto &p : arr)
 {
  std::cout << p.first << ", " << p.second << '\n';
 }
 std::cout << std::endl;
 std::sort(std::begin(arr), std::end(arr),
  [](const auto &p1, const auto &p2)
  {
   return usr::min(p1) < usr::min(p2);
  });
 for (const auto &p : arr)
 {
  std::cout << p.first << ", " << p.second << '\n';
 }
 std::cout << std::endl;
 return 0;
}

Its output is

4, 10
7, 6
3, 8
9, 1

7, 6
3, 8
9, 1
4, 10

9, 1
3, 8
4, 10
7, 6

It is clear from the code that max and min indeed look like properties of std::pair.

 
If they ARE meant to be compared and are the same type, you should probably be using a std::array. If they are two different types with some defined comparison operation, you're looking at an edge case for which custom code is probably suitable (especially as you'd probably want to document it properly).


Even if two objects have the same type they can be semantically different. So it is not always a good idea to substitute std::pair for std::array.
 
Secondly, getting the min and max of a pair is trivial. You can write min(p.first, p.second) with minimal effort, and is very readable. In fact, I would consider it considerably more readable than min(p).

Sometimes the more detailed code means its less readability. 

Nicol Bolas

unread,
Dec 11, 2017, 10:18:31 AM12/11/17
to ISO C++ Standard - Future Proposals
On Monday, December 11, 2017 at 9:31:55 AM UTC-5, Vlad from Moscow wrote:
I am not discussing "how it works". I want to collect opinions about introducing these functions.

My opinion is that adding these functions without a convincing motivation is putting the cart before the horse.

Jake Arkinstall

unread,
Dec 11, 2017, 10:20:52 AM12/11/17
to std-pr...@isocpp.org


On 11 Dec 2017 15:12, "'Vlad from Moscow' via ISO C++ Standard - Future Proposals" <std-pr...@isocpp.org> wrote:
Even if two objects have the same type they can be semantically different.

This is exactly my reasoning, too. Comparing semantically different objects makes little sense to me.

Sometimes the more detailed code means its less readability.

I agree. But I strongly disagree that this is one of those occasions.

Dan Raviv

unread,
Dec 11, 2017, 10:24:35 AM12/11/17
to std-pr...@isocpp.org
Perhaps a more general approach, which would also solve your use case trivially, is a proposal to allow std::pair<T,T> to be convertible to a range of T?

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.

Nicol Bolas

unread,
Dec 11, 2017, 11:17:26 AM12/11/17
to ISO C++ Standard - Future Proposals
On Monday, December 11, 2017 at 10:24:35 AM UTC-5, Dan Raviv wrote:
Perhaps a more general approach, which would also solve your use case trivially, is a proposal to allow std::pair<T,T> to be convertible to a range of T?

That would be a decidedly odd thing. It would imply that any type that is layout-compatible with `pair` would be able to do this.

Now, if you want to generalize this, such that, for any standard layout struct, a sequence of `T`s (using their natural alignment) can be converted into a range, then that might be OK. But I don't see the committee allowing that.
Reply all
Reply to author
Forward
0 new messages