home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c++.moderated      Moderated discussion of C++ superhackery      33,346 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 33,148 of 33,346   
   enrico.ecamail@googlemail.com to All   
   Mutable and non-mutable lambda functions   
   25 Jul 13 03:01:02   
   
   { Reformatted; please limit your lines to 70 characters -mod }   
      
   Hello,   
      
   I am familiarizing with C++11 and would like to write a class for   
   synchronizing threads, whose API gives the possibility of adding   
   threads to an internal container, then wait for them to end,   
   suspending the caller until either all or at least one have finished   
   their task.   
      
   Here is my implementation:   
      
   //============================================================================   
   // multi_wait.cpp   
      
   #include    
   #include    
   #include    
   #include    
   #include    
   #include    
      
   namespace ext   
   {   
      class multi_wait   
      {   
      public:   
        multi_wait() : my_confirmed(false), my_ulk(my_mutex) {}   
        ~multi_wait() { wait_all(); }   
      
        typedef std::list thlist_type;   
      
      public:   
        template    
        void add(Fn_T the_fn, Args_PP... the_args)   
        {   
          // Create a thread whose execution body is a wrapper of original   
   function   
          std::function wfn([=](Args_PP... args) mutable   
                                              {   
                                                the_fn(args...);   
                                                my_confirmed = true;   
                                                my_cv.notify_all();   
                                              });   
          my_thlist.push_back(std::thread(wfn, the_args...));   
        }   
      
        void wait_all()   
        {   
          thlist_type::iterator it;   
          for (it = my_thlist.begin(); it != my_thlist.end(); ++it)   
            if (it->joinable()) it->join();   
        }   
      
        void wait_first()   
        { my_cv.wait(my_ulk, [=]{ return my_confirmed; }); }   
      
      private:   
        thlist_type                  my_thlist;   
        std::condition_variable      my_cv;   
        bool                         my_confirmed;   
        std::mutex                   my_mutex;   
        std::unique_lock my_ulk;   
      };   
   } // namespace ext   
      
   int main()   
   {   
      ext::multi_wait mw;   
      
      std::srand(std::time(0));   
      for (int i = 0; i < 8; ++i)   
        mw.add([](int d){   
   std::this_thread::sleep_for(std::chrono::seconds(d)); }, std::rand()%10);   
      
      mw.wait_first();   
      std::cout << "First out" << std::endl;   
      mw.wait_all();   
      std::cout << "All out" << std::endl;   
      return 0;   
   }   
   //============================================================================   
      
   The lambda function in method "multi_wait::add" is declared mutable,   
   so I can call "my_cv.notify_all()", which is a non-const method of   
   std::condition_variable; if I remove the "mutable" storage modifier,   
   the compiler complains (gcc 4.7.2 does, 4.6.3 does not) because   
   "notify_all" cannot be called, being non-const.   
      
   My question is: why the compiler does not complain as well for   
   "my_confirmed" being modified? I would expect it should complain,   
   being "my_confirmed" and "my_cv" both members of "this", which is   
   captured as a pointer to const, as far as I understand.   
      
   Thanks in advance for your help,   
   eca   
      
      
   --   
         [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
         [ comp.lang.c++.moderated.    First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca