Topic: Providing a version of std::accumulate where the


Author: ricky.65@hotmail.com
Date: Mon, 1 Apr 2013 07:12:23 -0700 (PDT)
Raw View
------=_Part_772_30891042.1364825543221
Content-Type: text/plain; charset=ISO-8859-1

Hi, It would be beneficial if the Standard Library provided a version of
std::accumulate where passing an initial value is not necessary.

Having to provide an initial value can lead to errors and "surprising"
results.

Consider:
double darr[] = { 0.1, 0.2, 0.3 };
cout << std::accumulate(darr, darr + 3, 0);

This will print 0 which is usually not what is expected or wanted. 0.0
should have been passed as the initial value instead of the integer 0. This
is confusing for novices and is an easy trap to fall into especially as it
appears quite innocuous. Here is an example:
http://stackoverflow.com/questions/9599552/compute-mean-using-stdaccumulate-fails The
below version of accumulate avoids this problem by using an initial value
of value_type(0) and operator+ to sum up the elements.
template <typename InputIterator>
typename std::iterator_traits<InputIterator>::value_type accumulate (
InputIterator first, InputIterator last)
{
        typedef typename std::iterator_traits<InputIterator>::value_type
value_type;
        value_type result = value_type(0);
        while (first !=  last)
                result = result + *first++;

        return result;
}


Kind regards,

Riccardo Marcangelo

--

---
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.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/?hl=en.



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

<div><table id=3D"src_table_0" style=3D"border-collapse: collapse; font-fam=
ily: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Consol=
e', monospace; font-size: 12px; white-space: pre;"><tbody><tr id=3D"sl_svn1=
6_715"><td class=3D"source" style=3D"padding-left: 4px; white-space: pre-wr=
ap; vertical-align: top;"><span class=3D"com"><font color=3D"#000000">Hi,

It would be beneficial if the Standard Library provided a version of std::a=
ccumulate where passing an initial value is not necessary.<br></font></span=
></td></tr><tr id=3D"sl_svn16_716"><td class=3D"source" style=3D"padding-le=
ft: 4px; white-space: pre-wrap; vertical-align: top;"><span class=3D"com"><=
font color=3D"#000000"><br></font></span></td></tr><tr id=3D"sl_svn16_717">=
<td class=3D"source" style=3D"padding-left: 4px; white-space: pre-wrap; ver=
tical-align: top;"><span class=3D"com"><font color=3D"#000000">Having to pr=
ovide an initial value can lead to errors and "surprising" results.<br></fo=
nt></span></td></tr><tr id=3D"sl_svn16_718"><td class=3D"source" style=3D"p=
adding-left: 4px; white-space: pre-wrap; vertical-align: top;"><span class=
=3D"com"><font color=3D"#000000"><br></font></span></td></tr><tr id=3D"sl_s=
vn16_719"><td class=3D"source" style=3D"padding-left: 4px; white-space: pre=
-wrap; vertical-align: top;"><span class=3D"com"><font color=3D"#000000">Co=
nsider:
<br></font></span></td></tr><tr id=3D"sl_svn16_720"><td class=3D"source" st=
yle=3D"padding-left: 4px; white-space: pre-wrap; vertical-align: top;"><spa=
n class=3D"com"><font color=3D"#000000">double darr[] =3D { 0.1, 0.2, 0.3 }=
;<br></font></span></td></tr><tr id=3D"sl_svn16_721"><td class=3D"source" s=
tyle=3D"padding-left: 4px; white-space: pre-wrap; vertical-align: top;"><sp=
an class=3D"com"><font color=3D"#000000">cout &lt;&lt; std::accumulate(darr=
, darr + 3, 0);<br></font></span></td></tr><tr id=3D"sl_svn16_722"><td clas=
s=3D"source" style=3D"padding-left: 4px; white-space: pre-wrap; vertical-al=
ign: top;"><span class=3D"com"><font color=3D"#000000"><br></font></span></=
td></tr><tr id=3D"sl_svn16_723"><td class=3D"source" style=3D"padding-left:=
 4px; vertical-align: top;"><font color=3D"#000000"><span class=3D"com"><sp=
an style=3D"white-space: pre-wrap;">This will print 0 which is usually not =
what is expected or wanted. 0.0 should have been passed as the initial valu=
e instead of the integer 0.=20
This is confusing for novices and is an easy trap to fall into especially a=
s it appears quite innocuous.=20
Here is an example: </span><a href=3D"http://stackoverflow.com/questions/95=
99552/compute-mean-using-stdaccumulate-fails" style=3D"white-space: pre-wra=
p;">http://stackoverflow.com/questions/9599552/compute-mean-using-stdaccumu=
late-fails</a><span style=3D"white-space: pre-wrap;">
</span></span><span style=3D"white-space: pre-wrap;">    </span></font></td=
></tr><tr id=3D"sl_svn16_724"><td class=3D"source" style=3D"padding-left: 4=
px; white-space: pre-wrap; vertical-align: top;"></td></tr><tr id=3D"sl_svn=
16_725"><td class=3D"source" style=3D"padding-left: 4px; vertical-align: to=
p;"><span class=3D"com"><font color=3D"#000000"><span style=3D"white-space:=
 pre-wrap;">The below version of accumulate avoids this problem by using an=
 initial value of value_type(0) and operator+ to sum up the elements. </spa=
n></font></span></td></tr><tr id=3D"sl_svn16_726"><td class=3D"source" styl=
e=3D"padding-left: 4px; white-space: pre-wrap; vertical-align: top;"><span =
class=3D"pln"><font color=3D"#000000"><br></font></span></td></tr><tr id=3D=
"sl_svn16_727"><td class=3D"source" style=3D"padding-left: 4px; white-space=
: pre-wrap; vertical-align: top;"><font color=3D"#000000"><span class=3D"kw=
d">template</span><span class=3D"pln"> </span><span class=3D"pun">&lt;</spa=
n><span class=3D"kwd">typename</span><span class=3D"pln"> </span><span clas=
s=3D"typ">InputIterator</span><span class=3D"pun">&gt;</span><span class=3D=
"pln"><br></span></font></td></tr><tr id=3D"sl_svn16_728"><td class=3D"sour=
ce" style=3D"padding-left: 4px; white-space: pre-wrap; vertical-align: top;=
"></td></tr><tr id=3D"sl_svn16_729"><td class=3D"source" style=3D"padding-l=
eft: 4px; white-space: pre-wrap; vertical-align: top;"><font color=3D"#0000=
00"><span class=3D"kwd">typename</span><span class=3D"pln"> std</span><span=
 class=3D"pun">::</span><span class=3D"pln">iterator_traits</span><span cla=
ss=3D"pun">&lt;</span><span class=3D"typ">InputIterator</span><span class=
=3D"pun">&gt;::</span><span class=3D"pln">value_type accumulate </span><spa=
n class=3D"pun">(</span><span class=3D"typ">InputIterator</span><span class=
=3D"pln"> first</span><span class=3D"pun">,</span><span class=3D"pln"> </sp=
an><span class=3D"typ">InputIterator</span><span class=3D"pln"> </span><spa=
n class=3D"kwd">last</span><span class=3D"pun">)</span><span class=3D"pln">=
<br></span></font></td></tr><tr id=3D"sl_svn16_730"><td class=3D"source" st=
yle=3D"padding-left: 4px; white-space: pre-wrap; vertical-align: top;"><fon=
t color=3D"#000000"><span class=3D"pun">{</span><span class=3D"pln"><br></s=
pan></font></td></tr><tr id=3D"sl_svn16_731"><td class=3D"source" style=3D"=
padding-left: 4px; white-space: pre-wrap; vertical-align: top;"><font color=
=3D"#000000"><span class=3D"pln">&nbsp; &nbsp; &nbsp; &nbsp; </span><span c=
lass=3D"kwd">typedef</span><span class=3D"pln"> </span><span class=3D"kwd">=
typename</span><span class=3D"pln"> std</span><span class=3D"pun">::</span>=
<span class=3D"pln">iterator_traits</span><span class=3D"pun">&lt;</span><s=
pan class=3D"typ">InputIterator</span><span class=3D"pun">&gt;::</span><spa=
n class=3D"pln">value_type value_type</span><span class=3D"pun">;</span><sp=
an class=3D"pln"><br></span></font></td></tr><tr id=3D"sl_svn16_732"><td cl=
ass=3D"source" style=3D"padding-left: 4px; white-space: pre-wrap; vertical-=
align: top;"><font color=3D"#000000"><span class=3D"pln">&nbsp; &nbsp; &nbs=
p; &nbsp; value_type result </span><span class=3D"pun">=3D</span><span clas=
s=3D"pln"> value_type(0);</span></font></td></tr><tr id=3D"sl_svn16_733"><t=
d class=3D"source" style=3D"padding-left: 4px; white-space: pre-wrap; verti=
cal-align: top;"><span class=3D"pln"><font color=3D"#000000"><br></font></s=
pan></td></tr><tr id=3D"sl_svn16_734"><td class=3D"source" style=3D"padding=
-left: 4px; white-space: pre-wrap; vertical-align: top;"><font color=3D"#00=
0000"><span class=3D"pln">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class=3D=
"kwd">while</span><span class=3D"pln"> </span><span class=3D"pun">(</span><=
span class=3D"pln">first </span><span class=3D"pun">!=3D</span><span class=
=3D"pln"> &nbsp;</span><span class=3D"kwd">last</span><span class=3D"pun">)=
</span><span class=3D"pln"><br></span></font></td></tr><tr id=3D"sl_svn16_7=
35"><td class=3D"source" style=3D"padding-left: 4px; white-space: pre-wrap;=
 vertical-align: top;"><font color=3D"#000000"><span class=3D"pln">&nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result </span><span class=
=3D"pun">=3D</span><span class=3D"pln"> result </span><span class=3D"pun">+=
</span><span class=3D"pln"> </span><span class=3D"pun">*</span><span class=
=3D"pln">first</span><span class=3D"pun">++;</span><span class=3D"pln"> &nb=
sp; &nbsp; <br></span></font></td></tr><tr id=3D"sl_svn16_736"><td class=3D=
"source" style=3D"padding-left: 4px; white-space: pre-wrap; vertical-align:=
 top;"><span class=3D"pln"><font color=3D"#000000"><br></font></span></td><=
/tr><tr id=3D"sl_svn16_737"><td class=3D"source" style=3D"padding-left: 4px=
; white-space: pre-wrap; vertical-align: top;"><font color=3D"#000000"><spa=
n class=3D"pln">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class=3D"kwd">retu=
rn</span><span class=3D"pln"> result</span><span class=3D"pun">;</span><spa=
n class=3D"pln"><br></span></font></td></tr><tr id=3D"sl_svn16_738"><td cla=
ss=3D"source" style=3D"padding-left: 4px; white-space: pre-wrap; vertical-a=
lign: top;"><font color=3D"#000000"><span class=3D"pun">}</span><span class=
=3D"pln"><br></span></font></td></tr><tr id=3D"sl_svn16_739"></tr></tbody><=
/table></div><div><font color=3D"#000000"><br></font></div><div><font color=
=3D"#000000"><br></font></div><div><font color=3D"#000000">Kind regards,</f=
ont></div><div><font color=3D"#000000"><br></font></div><div><font color=3D=
"#000000">Riccardo Marcangelo</font></div><br>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_772_30891042.1364825543221--

.


Author: Marc <marc.glisse@gmail.com>
Date: Mon, 1 Apr 2013 11:17:49 -0700 (PDT)
Raw View
------=_Part_37_18828462.1364840269870
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Le lundi 1 avril 2013 16:12:23 UTC+2, rick...@hotmail.com a =E9crit :
>
> It would be beneficial if the Standard Library provided a version of=20
> std::accumulate where passing an initial value is not necessary.
>

Indeed, most of the time when I use accumulate it is without an initial=20
value.
=20

> The below version of accumulate avoids this problem by using an initial=
=20
> value of value_type(0) and operator+ to sum up the elements.=20
> template <typename InputIterator>
> typename std::iterator_traits<InputIterator>::value_type accumulate (
> InputIterator first, InputIterator last)
> {
>         typedef typename std::iterator_traits<InputIterator>::value_type=
=20
> value_type;
>         value_type result =3D value_type(0);
>         while (first !=3D  last)
>                 result =3D result + *first++;    =20
>
>         return result;
> }
>

Using a default constructed value_type would make more sense than=20
converting 0. And I think we would still want a functor (possibly defaulted=
=20
to std::plus<>, even if that can be slightly less good than writing +=20
directly).

But more important to me is avoiding the operation with the first element.=
=20
accumulate is very generic and that prevents it from using *first++ as the=
=20
initial value. However, if we create a new restricted version, I think it=
=20
shouldn't keep that extra +0.

Also, the use of + (as opposed to +=3D) has been criticized in the past. Th=
at=20
is something that a new version of accumulate may want to reconsider.

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/?hl=3Den.



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

Le lundi 1 avril 2013 16:12:23 UTC+2, rick...@hotmail.com a =E9crit&nbsp;:<=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div><table style=3D"border-col=
lapse:collapse;font-family:Monaco,'DejaVu Sans Mono','Bitstream Vera Sans M=
ono','Lucida Console',monospace;font-size:12px;white-space:pre"><tbody><tr>=
<td style=3D"padding-left:4px;white-space:pre-wrap;vertical-align:top"><spa=
n><font color=3D"#000000">It would be beneficial if the Standard Library pr=
ovided a version of std::accumulate where passing an initial value is not n=
ecessary.<br></font></span></td></tr></tbody></table></div></blockquote><di=
v><br>Indeed, most of the time when I use accumulate it is without an initi=
al value.<br>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin:=
 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left=
: 1ex;"><div><table style=3D"border-collapse: collapse; font-family: Monaco=
,'DejaVu Sans Mono','Bitstream Vera Sans Mono','Lucida Console',monospace; =
font-size: 12px; white-space: pre;"><tbody><tr><td style=3D"padding-left: 4=
px; white-space: pre-wrap; vertical-align: top;"><span><font color=3D"#0000=
00"></font></span></td></tr><tr><td style=3D"padding-left:4px;white-space:p=
re-wrap;vertical-align:top"></td></tr><tr><td style=3D"padding-left:4px;whi=
te-space:pre-wrap;vertical-align:top"></td></tr><tr><td style=3D"padding-le=
ft:4px;white-space:pre-wrap;vertical-align:top"></td></tr><tr><td style=3D"=
padding-left:4px;white-space:pre-wrap;vertical-align:top"></td></tr><tr><td=
 style=3D"padding-left:4px;white-space:pre-wrap;vertical-align:top"></td></=
tr><tr><td style=3D"padding-left:4px;white-space:pre-wrap;vertical-align:to=
p"></td></tr><tr><td style=3D"padding-left:4px;white-space:pre-wrap;vertica=
l-align:top"></td></tr><tr><td style=3D"padding-left:4px;vertical-align:top=
"></td></tr><tr><td style=3D"padding-left:4px;white-space:pre-wrap;vertical=
-align:top"></td></tr><tr><td style=3D"padding-left:4px;vertical-align:top"=
><span><font color=3D"#000000"><span style=3D"white-space:pre-wrap">The bel=
ow version of accumulate avoids this problem by using an initial value of v=
alue_type(0) and operator+ to sum up the elements. </span></font></span></t=
d></tr><tr><td style=3D"padding-left:4px;white-space:pre-wrap;vertical-alig=
n:top"><span><font color=3D"#000000"><br></font></span></td></tr><tr><td st=
yle=3D"padding-left:4px;white-space:pre-wrap;vertical-align:top"><font colo=
r=3D"#000000"><span>template</span><span> </span><span>&lt;</span><span>typ=
ename</span><span> </span><span>InputIterator</span><span>&gt;</span><span>=
<br></span></font></td></tr><tr><td style=3D"padding-left:4px;white-space:p=
re-wrap;vertical-align:top"></td></tr><tr><td style=3D"padding-left:4px;whi=
te-space:pre-wrap;vertical-align:top"><font color=3D"#000000"><span>typenam=
e</span><span> std</span><span>::</span><span>iterator_traits</span><span>&=
lt;</span><span>InputIter<wbr>ator</span><span>&gt;::</span><span>value_typ=
e accumulate </span><span>(</span><span>InputIterator</span><span> first</s=
pan><span>,</span><span> </span><span>InputIterator</span><span> </span><sp=
an>last</span><span>)</span><span><br></span></font></td></tr><tr><td style=
=3D"padding-left:4px;white-space:pre-wrap;vertical-align:top"><font color=
=3D"#000000"><span>{</span><span><br></span></font></td></tr><tr><td style=
=3D"padding-left:4px;white-space:pre-wrap;vertical-align:top"><font color=
=3D"#000000"><span>&nbsp; &nbsp; &nbsp; &nbsp; </span><span>typedef</span><=
span> </span><span>typename</span><span> std</span><span>::</span><span>ite=
rator_traits</span><span>&lt;</span><span>InputIter<wbr>ator</span><span>&g=
t;::</span><span>value_type value_type</span><span>;</span><span><br></span=
></font></td></tr><tr><td style=3D"padding-left:4px;white-space:pre-wrap;ve=
rtical-align:top"><font color=3D"#000000"><span>&nbsp; &nbsp; &nbsp; &nbsp;=
 value_type result </span><span>=3D</span><span> value_type(0);</span></fon=
t></td></tr><tr><td style=3D"padding-left:4px;white-space:pre-wrap;vertical=
-align:top"><span><font color=3D"#000000"><br></font></span></td></tr><tr><=
td style=3D"padding-left:4px;white-space:pre-wrap;vertical-align:top"><font=
 color=3D"#000000"><span>&nbsp; &nbsp; &nbsp; &nbsp; </span><span>while</sp=
an><span> </span><span>(</span><span>first </span><span>!=3D</span><span> &=
nbsp;</span><span>last</span><span>)</span><span><br></span></font></td></t=
r><tr><td style=3D"padding-left:4px;white-space:pre-wrap;vertical-align:top=
"><font color=3D"#000000"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; result </span><span>=3D</span><span> result </span><span>+</sp=
an><span> </span><span>*</span><span>first</span><span>++;</span><span> &nb=
sp; &nbsp; <br></span></font></td></tr><tr><td style=3D"padding-left:4px;wh=
ite-space:pre-wrap;vertical-align:top"><span><font color=3D"#000000"><br></=
font></span></td></tr><tr><td style=3D"padding-left:4px;white-space:pre-wra=
p;vertical-align:top"><font color=3D"#000000"><span>&nbsp; &nbsp; &nbsp; &n=
bsp; </span><span>return</span><span> result</span><span>;</span><span><br>=
</span></font></td></tr><tr><td style=3D"padding-left:4px;white-space:pre-w=
rap;vertical-align:top"><font color=3D"#000000"><span>}</span><span><br></s=
pan></font></td></tr><tr></tr></tbody></table></div></blockquote><div><br>U=
sing a default constructed value_type would make more sense than converting=
 0. And I think we would still want a functor (possibly defaulted to std::p=
lus&lt;&gt;, even if that can be slightly less good than writing + directly=
).<br><br>But more important to me is avoiding the operation with the first=
 element. accumulate is very generic and that prevents it from using *first=
++ as the initial value. However, if we create a new restricted version, I =
think it shouldn't keep that extra +0.<br><br>Also, the use of + (as oppose=
d to +=3D) has been criticized in the past. That is something that a new ve=
rsion of accumulate may want to reconsider.<br></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_37_18828462.1364840269870--

.