Mutable and non-mutable lambda functions capturing "this"
{ 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 <iostream>
#include <chrono>
#include <thread>
#include <condition_variable>
#include <functional>
#include <list>
namespace ext
{
class multi_wait
{
public:
multi_wait() : my_confirmed(false), my_ulk(my_mutex) {}
~multi_wait() { wait_all(); }
typedef std::list<std::thread> thlist_type;
public:
template <typename Fn_T, typename ...Args_PP>
void add(Fn_T the_fn, Args_PP... the_args)
{
// Create a thread whose execution body is a wrapper of original
function
std::function<void(Args_PP...)> 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<std::mutex> 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! ]