Topic: generalizing min/max for non-exact matching types?


Author: Peter Sommerlad <peter.sommerlad@hsr.ch>
Date: Fri, 23 Nov 2012 12:30:44 +0100
Raw View
Hi,

would a proposal to generalize std::min/std::max to accept arguments of (sl=
ightly) different types too much to ask for? I am not sure if allowing std:=
:min(1e10,'a') is useful, but often my students mix signed and unsigned typ=
es and can not use min() or max() in a straightforward way. With C++11 we h=
ave the machinery to implement that easily.

I am thinking of implementations like

#include <type_traits>
namespace MyMax{
template <typename T,typename U=3DT>
typename std::common_type<T const &, U const &>::type
max(T const &a, U const & b){
 return a < b ? b : a;
}

}

or=20

namespace MyMin{

template <typename T, typename U =3D T>
auto min(T const& a, U const& b)->decltype(a<b?a:b){
 return (a < b)? a : b ;
}
}

What do you think. Teach me, that we won't want that, otherwise I might fee=
l obliged to propose such a change.

Will it break existing code? I doubt, but you tell me better!

Thanks for teaching me

Regards
Peter.=20
--=20
Prof. Peter Sommerlad

Institut f=FCr Software: Bessere Software - Einfach, Schneller!
HSR Hochschule f=FCr Technik Rapperswil
Oberseestr 10, Postfach 1475, CH-8640 Rapperswil

http://ifs.hsr.ch http://cute-test.com http://linticator.com http://includa=
tor.com
tel:+41 55 222 49 84 =3D=3D mobile:+41 79 432 23 32
fax:+41 55 222 46 29 =3D=3D mailto:peter.sommerlad@hsr.ch





--=20




.


Author: DeadMG <wolfeinstein@gmail.com>
Date: Fri, 23 Nov 2012 03:44:24 -0800 (PST)
Raw View
------=_Part_126_1873493.1353671064084
Content-Type: text/plain; charset=ISO-8859-1

It's fairly contrived, but I can create code that would be broken.

struct Y {
    operator int() { return 5; }
};
struct X {
    operator Y() { return Y(); }
};

std::min<Y>(X(), X());

Currently, both arguments are converted to Y, and then converted to int
when compared. This is OK because there are two conversion sites, so two
implicit conversions can occur. However, your change would leave the second
argument as X, and would require two implicit conversions to compile lhs <
rhs, which is not permitted. Thus, this code would now fail to compile. In
addition, you will have problems where common_type<first, second>::type is
second, but a coder explicitly passed first as the template argument- now
the return type is different, so decltype(std::min<first>(args)) is now a
different type, and specialization or overload resolution or SFINAE or
std::is_same may no longer function correctly.

In addition, anyone who specialized std::min may have their specializations
broken, as they would be missing template arguments.

template<typename T> const my_class<T>& std::min<my_class<T>>(const
my_class<T>& lhs, const my_class<T>& rhs) {
    ...
}

Now not allowed, whereas if I recall correctly, previously was allowed.

--




------=_Part_126_1873493.1353671064084
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div>It's fairly contrived, but I can create code that would be broken.</di=
v><div><br></div><div>struct Y {</div><div>&nbsp; &nbsp; operator int() { r=
eturn 5; }</div><div>};</div><div>struct X {<br></div><div>&nbsp; &nbsp; op=
erator Y() { return Y(); }</div><div>};</div><div><br></div><div>std::min&l=
t;Y&gt;(X(), X());</div><div><br></div><div>Currently, both arguments are c=
onverted to Y, and then converted to int when compared. This is OK because =
there are two conversion sites, so two implicit conversions can occur. Howe=
ver, your change would leave the second argument as X, and would require tw=
o implicit conversions to compile lhs &lt; rhs, which is not permitted. Thu=
s, this code would now fail to compile. In addition, you will have problems=
 where common_type&lt;first, second&gt;::type is second, but a coder explic=
itly passed first as the template argument- now the return type is differen=
t, so decltype(std::min&lt;first&gt;(args)) is now a different type, and sp=
ecialization or overload resolution or SFINAE or std::is_same may no longer=
 function correctly.</div><div><br></div><div>In addition, anyone who speci=
alized std::min may have their specializations broken, as they would be mis=
sing template arguments.</div><div><br></div><div>template&lt;typename T&gt=
; const my_class&lt;T&gt;&amp; std::min&lt;my_class&lt;T&gt;&gt;(const my_c=
lass&lt;T&gt;&amp; lhs, const my_class&lt;T&gt;&amp; rhs) {</div><div>&nbsp=
; &nbsp; ...</div><div>}</div><div><br></div><div>Now not allowed, whereas =
if I recall correctly, previously was allowed.</div><div><br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_126_1873493.1353671064084--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Fri, 23 Nov 2012 19:12:01 +0100
Raw View
Le 23/11/12 12:44, DeadMG a =E9crit :
> It's fairly contrived, but I can create code that would be broken.
>
> struct Y {
>     operator int() { return 5; }
> };
> struct X {
>     operator Y() { return Y(); }
> };
>
> std::min<Y>(X(), X());
>
> Currently, both arguments are converted to Y, and then converted to=20
> int when compared. This is OK because there are two conversion sites,=20
> so two implicit conversions can occur. However, your change would=20
> leave the second argument as X, and would require two implicit=20
> conversions to compile lhs < rhs, which is not permitted. Thus, this=20
> code would now fail to compile. In addition, you will have problems=20
> where common_type<first, second>::type is second, but a coder=20
> explicitly passed first as the template argument- now the return type=20
> is different, so decltype(std::min<first>(args)) is now a different=20
> type, and specialization or overload resolution or SFINAE or=20
> std::is_same may no longer function correctly.
>
Hi,
maybe changing the definition of max we could avoid breaking (See=20
below). The code uses a trait has_common_type so that we can use=20
common_type SFINAE friendly. I have not followed the thread about SFINAE=20
friendly common_type, so maybe there are better options.
> In addition, anyone who specialized std::min may have their=20
> specializations broken, as they would be missing template arguments.
>
> template<typename T> const my_class<T>& std::min<my_class<T>>(const=20
> my_class<T>& lhs, const my_class<T>& rhs) {
>     ...
> }
>
> Now not allowed, whereas if I recall correctly, previously was allowed.
>
Isn't this specialization UB?

Vicente

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D


#include <type_traits>
#include <iostream>
#include <algorithm>
#include <utility>

template <typename T, typename U>
struct has_common_type : std::false_type{};

namespace myns {

template <typename CT, typename T, typename U>
typename std::enable_if<
   has_common_type<T,U>::value,
   CT
   >::type
max(T const &a, U const & b){
   return CT(a) < CT(b) ? b : a;
}

template <typename T>
T max(T const &a, T const & b){
   return a < b ? b : a;
}

template <typename T, typename U>
typename std::enable_if<
   has_common_type<T,U>::value,
   typename std::common_type<T const &, U const &>::type
 >::type
max(T const &a, U const & b)
{
   return a < b ? b : a;
}

}

struct Y {
     operator int() const { return 5; }
};
struct X {
     operator Y() const { return Y(); }
};

template <typename OS>
OS& operator<<(OS& os, const Y& v) {
   os << int(v);
   return os;
}

template <>
struct has_common_type<unsigned char,int> : std::true_type{};
template <>
struct has_common_type<X,Y> : std::true_type{};

int main()
{

   std ::cout << std::max<Y>(X(), X()) << std::endl;
   std ::cout << myns::max<Y>(X(), X()) << std::endl;
   unsigned char v1 =3D 127;
   int v2 =3D 2;
   std ::cout << myns::max(v1, v2) << std::endl;

   return 0;
}

=3D=3D=3D=3D=3D=3D=3D=3D
returns in
=3D=3D=3D=3D=3D=3D=3D=3D

5
5
127

--=20




.


Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Fri, 23 Nov 2012 21:06:43 +0100
Raw View
--089e0118499c607dad04cf2f1f02
Content-Type: text/plain; charset=ISO-8859-1

2012/11/23 Peter Sommerlad <peter.sommerlad@hsr.ch>

> Hi,
>
> would a proposal to generalize std::min/std::max to accept arguments of
> (slightly) different types too much to ask for? I am not sure if allowing
> std::min(1e10,'a') is useful, but often my students mix signed and unsigned
> types and can not use min() or max() in a straightforward way. With C++11
> we have the machinery to implement that easily.
>

You can try that, but let me remark that Howard had tried it once with

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2199.html

and this was not accepted. I'm not saying that a future one needs to fail
as well, but this one gives you some hints about tricky issues.

- Daniel

--




--089e0118499c607dad04cf2f1f02
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div class=3D"gmail_quote">2012/11/23 Peter Sommerlad <span dir=3D"ltr">&lt=
;<a href=3D"mailto:peter.sommerlad@hsr.ch" target=3D"_blank">peter.sommerla=
d@hsr.ch</a>&gt;</span><br><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi,<br>
<br>
would a proposal to generalize std::min/std::max to accept arguments of (sl=
ightly) different types too much to ask for? I am not sure if allowing std:=
:min(1e10,&#39;a&#39;) is useful, but often my students mix signed and unsi=
gned types and can not use min() or max() in a straightforward way. With C+=
+11 we have the machinery to implement that easily.<br>
</blockquote><div><br>You can try that, but let me remark that Howard had t=
ried it once with<br><br><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/=
docs/papers/2007/n2199.html">http://www.open-std.org/jtc1/sc22/wg21/docs/pa=
pers/2007/n2199.html</a><br>
<br>and this was not accepted. I&#39;m not saying that a future one needs t=
o fail as well, but this one gives you some hints about tricky issues.<br><=
br>- Daniel<br><br></div></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--089e0118499c607dad04cf2f1f02--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Fri, 23 Nov 2012 21:15:02 +0100
Raw View
This is a multi-part message in MIME format.
--------------030803080308070007030505
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 23/11/12 21:06, Daniel Kr=FCgler a =E9crit :
> 2012/11/23 Peter Sommerlad <peter.sommerlad@hsr.ch=20
> <mailto:peter.sommerlad@hsr.ch>>
>
>     Hi,
>
>     would a proposal to generalize std::min/std::max to accept
>     arguments of (slightly) different types too much to ask for? I am
>     not sure if allowing std::min(1e10,'a') is useful, but often my
>     students mix signed and unsigned types and can not use min() or
>     max() in a straightforward way. With C++11 we have the machinery
>     to implement that easily.
>
>
> You can try that, but let me remark that Howard had tried it once with
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2199.html
>
> and this was not accepted. I'm not saying that a future one needs to=20
> fail as well, but this one gives you some hints about tricky issues.
>
>
Do you remember why was not accepted?

Vicente

--=20




--------------030803080308070007030505
Content-Type: text/html; charset=ISO-8859-1

<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">Le 23/11/12 21:06, Daniel Kr&uuml;gler a
      &eacute;crit&nbsp;:<br>
    </div>
    <blockquote
cite="mid:CAGNvRgBXbpxrrjhJ1JFUdfmiKYpnyaGtFoGfKMsmbVvpuAqLMg@mail.gmail.com"
      type="cite">
      <div class="gmail_quote">2012/11/23 Peter Sommerlad <span
          dir="ltr">&lt;<a moz-do-not-send="true"
            href="mailto:peter.sommerlad@hsr.ch" target="_blank">peter.sommerlad@hsr.ch</a>&gt;</span><br>
        <blockquote class="gmail_quote" style="margin:0 0 0
          .8ex;border-left:1px #ccc solid;padding-left:1ex">
          Hi,<br>
          <br>
          would a proposal to generalize std::min/std::max to accept
          arguments of (slightly) different types too much to ask for? I
          am not sure if allowing std::min(1e10,'a') is useful, but
          often my students mix signed and unsigned types and can not
          use min() or max() in a straightforward way. With C++11 we
          have the machinery to implement that easily.<br>
        </blockquote>
        <div><br>
          You can try that, but let me remark that Howard had tried it
          once with<br>
          <br>
          <a moz-do-not-send="true"
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2199.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2199.html</a><br>
          <br>
          and this was not accepted. I'm not saying that a future one
          needs to fail as well, but this one gives you some hints about
          tricky issues.<br>
          <br>
        </div>
      </div>
      <br>
    </blockquote>
    Do you remember why was not accepted?<br>
    <br>
    Vicente<br>
    <br>
  </body>
</html>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--------------030803080308070007030505--

.


Author: Howard Hinnant <howard.hinnant@gmail.com>
Date: Fri, 23 Nov 2012 15:19:00 -0500
Raw View
On Nov 23, 2012, at 3:15 PM, "Vicente J. Botet Escriba" <vicente.botet@wana=
doo.fr> wrote:

> Le 23/11/12 21:06, Daniel Kr=FCgler a =E9crit :
>> 2012/11/23 Peter Sommerlad <peter.sommerlad@hsr.ch>
>> Hi,
>>=20
>> would a proposal to generalize std::min/std::max to accept arguments of =
(slightly) different types too much to ask for? I am not sure if allowing s=
td::min(1e10,'a') is useful, but often my students mix signed and unsigned =
types and can not use min() or max() in a straightforward way. With C++11 w=
e           have the machinery to implement that easily.
>>=20
>> You can try that, but let me remark that Howard had tried it once with
>>=20
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2199.html
>>=20
>> and this was not accepted. I'm not saying that a future one needs to fai=
l as well, but this one gives you some hints about tricky issues.
>>=20
>>=20
> Do you remember why was not accepted?

The feedback was: It's too complicated.

I'm not positive whether that referred to the specification, implementation=
 or both.

Howard

--=20




.


Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Fri, 23 Nov 2012 21:33:01 +0100
Raw View
--14dae9cdc76b676f8e04cf2f7d92
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

2012/11/23 Vicente J. Botet Escriba <vicente.botet@wanadoo.fr>

>  Le 23/11/12 21:06, Daniel Kr=FCgler a =E9crit :
>
> 2012/11/23 Peter Sommerlad <peter.sommerlad@hsr.ch>
>
>> Hi,
>>
>> would a proposal to generalize std::min/std::max to accept arguments of
>> (slightly) different types too much to ask for? I am not sure if allowin=
g
>> std::min(1e10,'a') is useful, but often my students mix signed and unsig=
ned
>> types and can not use min() or max() in a straightforward way. With C++1=
1
>> we have the machinery to implement that easily.
>>
>
> You can try that, but let me remark that Howard had tried it once with
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2199.html
>
> and this was not accepted. I'm not saying that a future one needs to fail
> as well, but this one gives you some hints about tricky issues.
>
>  Do you remember why was not accepted?
>
>
Howard already responded, so I'm only adding some minor remark (I wasn't
during the meeting where the proposal was refused, and I cannot find any
notes about the reasons of the rejection).

I also want to clarify that my above note about "hints about tricky issues"
was meant to emphasize that Howard's proposal had really carefully be
designed and that you should look at it, because it takes care of otherwise
"easy-to-miss" traps.

I also remember that Sebastian Gesemann had some interesting remarks to
minmax in the past:

https://groups.google.com/d/topic/comp.std.c++/OA6d35m4mFw/discussion

- Daniel

--=20




--14dae9cdc76b676f8e04cf2f7d92
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div class=3D"gmail_quote">2012/11/23 Vicente J. Botet Escriba <span dir=3D=
"ltr">&lt;<a href=3D"mailto:vicente.botet@wanadoo.fr" target=3D"_blank">vic=
ente.botet@wanadoo.fr</a>&gt;</span><br><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

 =20
   =20
 =20
  <div bgcolor=3D"#FFFFFF" text=3D"#000000">
    <div>Le 23/11/12 21:06, Daniel Kr=FCgler a
      =E9crit=A0:<br>
    </div><div><div class=3D"h5">
    <blockquote type=3D"cite">
      <div class=3D"gmail_quote">2012/11/23 Peter Sommerlad <span dir=3D"lt=
r">&lt;<a href=3D"mailto:peter.sommerlad@hsr.ch" target=3D"_blank">peter.so=
mmerlad@hsr.ch</a>&gt;</span><br>
        <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border=
-left:1px #ccc solid;padding-left:1ex">
          Hi,<br>
          <br>
          would a proposal to generalize std::min/std::max to accept
          arguments of (slightly) different types too much to ask for? I
          am not sure if allowing std::min(1e10,&#39;a&#39;) is useful, but
          often my students mix signed and unsigned types and can not
          use min() or max() in a straightforward way. With C++11 we
          have the machinery to implement that easily.<br>
        </blockquote>
        <div><br>
          You can try that, but let me remark that Howard had tried it
          once with<br>
          <br>
          <a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/200=
7/n2199.html" target=3D"_blank">http://www.open-std.org/jtc1/sc22/wg21/docs=
/papers/2007/n2199.html</a><br>
          <br>
          and this was not accepted. I&#39;m not saying that a future one
          needs to fail as well, but this one gives you some hints about
          tricky issues.<br></div>
      </div>
      <br>
    </blockquote></div></div>
    Do you remember why was not accepted?<span class=3D"HOEnZb"><font color=
=3D"#888888"><br>
    <br></font></span></div></blockquote><br></div>Howard already responded=
, so I&#39;m only adding some minor remark (I wasn&#39;t during the meeting=
 where the proposal was refused, and I cannot find any notes about the reas=
ons of the rejection).<br>
<br>I also want to clarify that my above note about &quot;hints about
          tricky issues&quot; was meant to emphasize that Howard&#39;s prop=
osal had really carefully be designed and that you should look at it, becau=
se it takes care of otherwise &quot;easy-to-miss&quot; traps.<br><br>I also=
 remember that Sebastian Gesemann had some interesting remarks to minmax in=
 the past:<br>
<br><a href=3D"https://groups.google.com/d/topic/comp.std.c++/OA6d35m4mFw/d=
iscussion">https://groups.google.com/d/topic/comp.std.c++/OA6d35m4mFw/discu=
ssion</a><br><br>- Daniel<br><br>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--14dae9cdc76b676f8e04cf2f7d92--

.


Author: Marshall Clow <mclow.lists@gmail.com>
Date: Fri, 23 Nov 2012 14:35:51 -0800
Raw View
Since we're talking about min and max, how about "enhancing" them to take an arbitrary number of arguments?

I know that min/max now take initializer lists, but that requires creating a data structure - doesn't it?

And there is max_element - but that requires a pair of iterators.

I was thinking about being able to write:
 int jenny = std::max ( 8, 6, 7, 5, 3, 0, 9 );

and have no memory allocation and only six calls to operator <.

-- Marshall

P.S. I wouldn't really mind if we called this "max_element", and left "max" for the two item case.

--




.


Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Fri, 23 Nov 2012 23:56:34 +0100
Raw View
--bcaec501634bca0e7904cf317edf
Content-Type: text/plain; charset=ISO-8859-1

2012/11/23 Marshall Clow <mclow.lists@gmail.com>

>
> Since we're talking about min and max, how about "enhancing" them to take
> an arbitrary number of arguments?
>
> I know that min/max now take initializer lists, but that requires creating
> a data structure - doesn't it?
>

In the general case: Yes. But implementations can optimize some cases (Not
those with dynamic runtime values, though)


> And there is max_element - but that requires a pair of iterators.
>
> I was thinking about being able to write:
>         int jenny = std::max ( 8, 6, 7, 5, 3, 0, 9 );
>
> and have no memory allocation and only six calls to operator <.
>

I think that this particular (not a real-world) example doesn't require
actually memory. But I agree with
the issue in principle. I found the intermediate variadic forms very nice.
The only disadvantage was a slight (but I don't think unsolvable) problem
for the case with a trailing comparator object. I would like to re-awake
this proposal:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2551.pdf

which was superseeded by

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2722.pdf

(and followups) at that time.

Naming-wise I don't think that max_element is a good choice, it is
misleading, because the *_element templates have a common property to work
on ranges and return an iterator. This directly supports the empty-range
case, but a variadic max overload with no arguments wouldn't make sense and
the usage would be different. I strongly suggest to keep with the max name
and I don't see how that would be problematic.

- Daniel

--




--bcaec501634bca0e7904cf317edf
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div class=3D"gmail_quote">2012/11/23 Marshall Clow <span dir=3D"ltr">&lt;<=
a href=3D"mailto:mclow.lists@gmail.com" target=3D"_blank">mclow.lists@gmail=
..com</a>&gt;</span><br><blockquote class=3D"gmail_quote" style=3D"margin:0 =
0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Since we&#39;re talking about min and max, how about &quot;enhancing&quot; =
them to take an arbitrary number of arguments?<br>
<br>
I know that min/max now take initializer lists, but that requires creating =
a data structure - doesn&#39;t it?<br></blockquote><div><br>In the general =
case: Yes. But implementations can optimize some cases (Not those with dyna=
mic runtime values, though)<br>
=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde=
r-left:1px #ccc solid;padding-left:1ex">

And there is max_element - but that requires a pair of iterators.<br>
<br>
I was thinking about being able to write:<br>
=A0 =A0 =A0 =A0 int jenny =3D std::max ( 8, 6, 7, 5, 3, 0, 9 );<br>
<br>
and have no memory allocation and only six calls to operator &lt;.<br></blo=
ckquote><div><br>I think that this particular (not a real-world) example do=
esn&#39;t require actually memory. But I agree with<br></div></div>the issu=
e in principle. I found the intermediate variadic forms very nice. The only=
 disadvantage was a slight (but I don&#39;t think unsolvable) problem for t=
he case with a trailing comparator object. I would like to re-awake this pr=
oposal:<br>
<br><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n255=
1.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2551.pdf</a=
><br><br>which was superseeded by<br><br><a href=3D"http://www.open-std.org=
/jtc1/sc22/wg21/docs/papers/2008/n2722.pdf">http://www.open-std.org/jtc1/sc=
22/wg21/docs/papers/2008/n2722.pdf</a><br>
<br>(and followups) at that time.<br><br>Naming-wise I don&#39;t think that=
 max_element is a good choice, it is misleading, because the *_element temp=
lates have a common property to work on ranges and return an iterator. This=
 directly supports the empty-range case, but a variadic max overload with n=
o arguments wouldn&#39;t make sense and the usage would be different. I str=
ongly suggest to keep with the max name and I don&#39;t see how that would =
be problematic.<br>
<br>- Daniel<br>=A0<br>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--bcaec501634bca0e7904cf317edf--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sat, 24 Nov 2012 00:04:41 +0100
Raw View
Le 23/11/12 12:44, DeadMG a =E9crit :
>
>
> In addition, anyone who specialized std::min may have their=20
> specializations broken, as they would be missing template arguments.
>
> template<typename T> const my_class<T>& std::min<my_class<T>>(const=20
> my_class<T>& lhs, const my_class<T>& rhs) {
>     ...
> }
>
> Now not allowed, whereas if I recall correctly, previously was allowed.
>
>
After re-reading the specialization. Isn't this partial function=20
template specialization incorrect in C++?

Best,
Vicente

--=20




.


Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Fri, 14 Dec 2012 05:54:30 -0800 (PST)
Raw View
------=_Part_460_15902983.1355493270763
Content-Type: text/plain; charset=ISO-8859-1

On Friday, November 23, 2012 11:35:55 PM UTC+1, Marshall wrote:

>
> Since we're talking about min and max, how about "enhancing" them to take
> an arbitrary number of arguments?
>

That's a different subject.
I run into the original issue (unmatched input types) all the time.

What'd be the problem with this variant?

template <typename T, typename U = T>
auto min(T a, U b)->decltype(a < b ? a : b)
{
return a < b ? a : b;
}

--




------=_Part_460_15902983.1355493270763
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On Friday, November 23, 2012 11:35:55 PM UTC+1, Marshall wrote:<br><blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;">
<br>Since we're talking about min and max, how about "enhancing" them to ta=
ke an arbitrary number of arguments?
<br></blockquote><div>&nbsp;</div><div>That's a different subject.</div><di=
v>I run into the original issue (unmatched input types) all the time.</div>=
<div><br></div><div><div>What'd be the problem with this variant?</div><div=
><br></div><div>template &lt;typename T, typename U =3D T&gt;&nbsp;</div><d=
iv>auto min(T a, U b)-&gt;decltype(a &lt; b ? a : b)</div><div>{&nbsp;</div=
><div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>retu=
rn a &lt; b ? a : b;&nbsp;</div><div>}</div></div><div><br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_460_15902983.1355493270763--

.