Topic: range-for should call for_each function if it has a one?


Author: euloanty@live.com
Date: Tue, 9 Oct 2018 05:05:44 -0700 (PDT)
Raw View
------=_Part_1830_30506537.1539086744157
Content-Type: multipart/alternative;
 boundary="----=_Part_1831_2106843720.1539086744158"

------=_Part_1831_2106843720.1539086744158
Content-Type: text/plain; charset="UTF-8"

I think it is painful and noisy to write iterators in order to support
range-for loop.

Here are my reasons:
1: semantics of range-for loop are not necessarily equivalent to access
every iterator in the range.
2: For many containers, defining iterators are harder than defining the
range-for loop directly.
3: It is painful to write iterators to support simple data structures.
4: For containers like std::deque, std::set, std::map and even lists, using
iterators to traverse the entire container lose a huge amount of
performance compared to define a universal for_each function.

For example, if I have a binary search tree:

template<typename T>
class bst
{
};


template<typename T,typename Callback>
void inorder_traverse(const bstnode<T> *p,Callback &&F)
{
if(p->left())
inorder_travel(p->left(),F);
F(p->value());
if(p->right())
inorder_travel(p->right(),F);
}
template<typename T,typename Callback>
inline void for_each(const bst<T> &t,Callback &&F)
{
if(t.root())
inorder_traverse(t.root(),std::forward<Callback>(F));
}



bst<std::size_t> b;
std::size_t sum(0);
for(const auto &ele : b)    // will check whether the "for_each" function
is defined for the container. If it does have one, call this first.
    sum+=ele;

this will be equivalent to:

bst<std::size_t> b;
std::size_t sum(0);
for_each(b,[&](const auto &ele)
{
    sum+=ele;
});

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9ba3d13b-3044-4223-afd0-218e8ba06893%40isocpp.org.

------=_Part_1831_2106843720.1539086744158
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>I think it is painful and noisy to write iterators in=
 order to support range-for loop.</div><div><br></div><div>Here are my reas=
ons:</div><div>1: semantics of range-for loop are not necessarily equivalen=
t to access every iterator in the range.</div><div>2: For many containers, =
defining iterators are harder than defining the range-for loop directly.</d=
iv><div>3: It is painful to write iterators to support simple data structur=
es.</div><div>4: For containers like std::deque, std::set, std::map and eve=
n lists, using iterators to=C2=A0traverse the entire container lose a huge =
amount of performance compared to define a universal for_each function.</di=
v><div><br></div><div>For example, if I have a binary search tree:</div><di=
v><br></div><div>template&lt;typename T&gt;</div><div>class bst</div><div>{=
<br></div><div>};</div><div><br></div><div><br></div><div>template&lt;typen=
ame T,typename Callback&gt;</div><div>void inorder_traverse(const bstnode&l=
t;T&gt; *p,Callback &amp;&amp;F)</div><div>{</div><div><span style=3D"white=
-space:pre"> </span>if(p-&gt;left())</div><div><span style=3D"white-space:p=
re">  </span>inorder_travel(p-&gt;left(),F);</div><div><span style=3D"white=
-space:pre"> </span>F(p-&gt;value());</div><div><span style=3D"white-space:=
pre"> </span>if(p-&gt;right())</div><div><span style=3D"white-space:pre">  =
</span>inorder_travel(p-&gt;right(),F);</div><div>}</div><div>template&lt;t=
ypename T,typename Callback&gt;</div><div>inline void for_each(const bst&lt=
;T&gt; &amp;t,Callback &amp;&amp;F)</div><div>{</div><div><span style=3D"wh=
ite-space:pre"> </span>if(t.root())</div><div><span style=3D"white-space:pr=
e">  </span>inorder_traverse(t.root(),std::forward&lt;Callback&gt;(F));</di=
v><div>}</div><div><br></div><div><br></div><div><br></div><div>bst&lt;std:=
:size_t&gt; b;=C2=A0</div><div>std::size_t sum(0);<br></div><div>for(const =
auto &amp;ele : b)=C2=A0 =C2=A0 // will check whether the &quot;for_each&qu=
ot; function is defined for the container. If it does have one, call this f=
irst.<br></div><div>=C2=A0 =C2=A0 sum+=3Dele;</div><div><br></div><div>this=
 will be equivalent to:</div><div><br></div><div><div>bst&lt;std::size_t&gt=
; b;=C2=A0</div><div>std::size_t sum(0);<br></div><div>for_each(b,[&amp;](c=
onst auto &amp;ele)</div></div><div>{</div><div>=C2=A0 =C2=A0 sum+=3Dele;<b=
r></div><div>});</div><div><br></div></div>

<p></p>

-- <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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/9ba3d13b-3044-4223-afd0-218e8ba06893%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/9ba3d13b-3044-4223-afd0-218e8ba06893=
%40isocpp.org</a>.<br />

------=_Part_1831_2106843720.1539086744158--

------=_Part_1830_30506537.1539086744157--

.