<div dir="ltr"><div>I was thinking in the case where one has a function, member function, or std::function already on hand that using "for_each(Range, Fn);" is succinct, but when digging into the details I think this makes it too easy to copy std::function objects or lambdas with value captures unnecessarily.</div><div><br></div><div>Here are some example use cases and why I'm convinced you're right and range based for is a more reliable syntax:</div><div><br></div><div>void doStuff(const Parameter& P); // doStuff may be a free function declaration</div><div>std::function<void (const Parameter&)> doStuff; // It might be a std::function</div><div><br></div><div>for (const Parameter &P : Parameters) // <-- Can expand copies here accidentally</div><div>   doStuff(P);</div><div><br></div><div>for_each(Parameters, doStuff); // <-- One less declaration.</div><div>                                                  // Less chance to copy the values from the iterators, but will</div><div>                                                  // pass doStuff by value. Prefer range based for.</div><div><br></div><div>for_each(Parameters, [&](const auto &P) -> void { doStuff(P) }); </div><div>// Less readable than range based for and copies the lamba object. I prefer range based for.</div><div> </div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Sep 4, 2017 at 6:32 PM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Not sure I follow - you have to write the type name in the parameter or in the range-based-for, similar mistakes in either case, right?</div><div class="HOEnZb"><div class="h5"><br><div class="gmail_quote"><div dir="ltr">On Mon, Sep 4, 2017 at 5:50 PM Keith Wyss <<a href="mailto:wyssman@gmail.com" target="_blank">wyssman@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto">I like for_each because it offers one less place to mistakenly capture by value.</div><div class="gmail_extra"><br><div class="gmail_quote">On Sep 4, 2017 1:22 PM, "David Blaikie" <<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Mon, Sep 4, 2017 at 1:16 PM Keith Wyss <<a href="mailto:wyssman@gmail.com" target="_blank">wyssman@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto">It is an equivalent concept to range based for loop. Its not strictly necessary, but neither is std::for_each.</div></blockquote><div><br>Right - but std::for_each existed before the range based for loop (& admittedly, before lambdas too). I'm not sure of the motivation for this given C++11 features/today's code.<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="gmail_extra"><br><div class="gmail_quote">On Sep 4, 2017 9:20 AM, "David Blaikie" <<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">What use case do you have for this over a range-based-for loop?</div><br><div class="gmail_quote"><div dir="ltr">On Sat, Sep 2, 2017 at 6:08 PM Keith via Phabricator via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">kpw created this revision.<br>
<br>
There are a few range based wrappers llvm provides already. They're handy and I<br>
couldn't find one for std::for_each, so I'm adding it.<br>
<br>
<br>
<a href="https://reviews.llvm.org/D37417" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D37417</a><br>
<br>
Files:<br>
  include/llvm/ADT/STLExtras.h<br>
  unittests/ADT/STLExtrasTest.<wbr>cpp<br>
<br>
<br>
Index: unittests/ADT/STLExtrasTest.<wbr>cpp<br>
==============================<wbr>==============================<wbr>=======<br>
--- unittests/ADT/STLExtrasTest.<wbr>cpp<br>
+++ unittests/ADT/STLExtrasTest.<wbr>cpp<br>
@@ -318,4 +318,14 @@<br>
   EXPECT_EQ(7, V[3]);<br>
 }<br>
<br>
+TEST(STLExtrasTest, ForEach) {<br>
+  std::vector<std::pair<int, int>> V = {{1, 2}, {3, 4}, {5, 6}};<br>
+  std::vector<int> Evens{};<br>
+  auto BackInserter = std::back_inserter(Evens);<br>
+  for_each(V,<br>
+           [&](std::pair<int, int> Element) { BackInserter = Element.second; });<br>
+  std::vector<int> ExpectedEvens = {2, 4, 6};<br>
+  EXPECT_EQ(Evens, ExpectedEvens);<br>
+}<br>
+<br>
 }<br>
Index: include/llvm/ADT/STLExtras.h<br>
==============================<wbr>==============================<wbr>=======<br>
--- include/llvm/ADT/STLExtras.h<br>
+++ include/llvm/ADT/STLExtras.h<br>
@@ -852,6 +852,13 @@<br>
   return std::find_if_not(std::begin(<wbr>Range), std::end(Range), P);<br>
 }<br>
<br>
+/// Provide wrapper to std::for_each which take ranges instead of having to<br>
+/// pass begin/end explicitly.<br>
+template <typename R, typename UnaryFunction><br>
+UnaryFunction for_each(R &&Range, UnaryFunction F) {<br>
+  return std::for_each(std::begin(<wbr>Range), std::end(Range), F);<br>
+}<br>
+<br>
 /// Provide wrappers to std::remove_if which take ranges instead of having to<br>
 /// pass begin/end explicitly.<br>
 template <typename R, typename UnaryPredicate><br>
<br>
<br>
______________________________<wbr>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
</blockquote></div>
</blockquote></div></div>
</blockquote></div></div>
</blockquote></div></div>
</blockquote></div>
</div></div></blockquote></div><br></div>