Transform hand written loop to std library call

  • A+
Category:Languages

I have recently watched the talk from Sean Parent about C++ seasoning from 2013. If I understood him right, he says that you can eliminate almost all (all?) hand written loops from your code. My question is how to achieve this? Let's consider the following code:

class ProgressDialog {   //interesting part of that class   void SetPosition(int position);   bool IsCancelRequested();   void SetHeader(const std::string& status); } void foo( const std::vector<std::string>& v) {   ProgressDialog dlg;   long position = 0;   for( const auto& s : v)   {     ++position;     dlg.SetPosition(position);     dlg.SetHeader("Processing"+ s);     DoSomethingThatTakesSomeTime(s);     if(dlg.IsCancelRequested()) break;   } } 

Is there a way to refactor away the hand written loop?

 


I'm not sure if this adds any clarity, but it is an attempt to refactor the concept of the loop and early break.

#include <string> #include <vector> #include <ciso646>  struct ProgressDialog {   //interesting part of that class   void SetPosition(int position);   bool IsCancelRequested();   void SetHeader(const std::string& status); }; void DoSomethingThatTakesSomeTime(std::string const&);  // iterate over a container, calling func with the current value. // if func returns false, cease iterating immediately. // return true if terminated early // note: func must return false if it wishes early termination, // otherwise true template<class Cont, class F>  auto for_each_while(Cont&& container, F&& func) {     for(auto&& s : container)         if (not func(s))              return true;     return false; }  void foo( const std::vector<std::string>& v) {     auto update_dialog =      [position = 0, dlg = ProgressDialog()](auto&& s) mutable     {         ++position;         dlg.SetPosition(position);         dlg.SetHeader("Processing"+ s);         DoSomethingThatTakesSomeTime(s);         return !dlg.IsCancelRequested();     };     for_each_while(v, update_dialog); } 

And here is some std library abuse which achieves the same thing.

I strongly suggest that you do not do this, as it is not clear to the casual reader what is going on!

void foo( const std::vector<std::string>& v) {     int position = 0;     auto dlg = ProgressDialog();      std::find_if(begin(v), end(v),                   [&](auto&& s)     {         ++position;         dlg.SetPosition(position);         dlg.SetHeader("Processing"+ s);         DoSomethingThatTakesSomeTime(s);         return dlg.IsCancelRequested();     }); } 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: