Re: Mutable and non-mutable lambda functions capturing "this"
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:
[..]
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.
This looks like a defect of gcc 4.7.2 to me. See below for the why.
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.
Your code example is an unfortunate example for an unexpected "gotcha!"
of C++11 lambda capturing rules related to "this". Because of the
complexity of your code example, let me provide a simpler example that
demonstrates the problem you are observing:
struct M {
bool non_const() { return false; };
};
struct S {
S() { [=]() { state = m.non_const(); }(); }
M m;
bool state;
};
S s;
This code is supposed to be *well-formed*, because the effect of using
the capture-default = in a non-static member function is to bind a copy
of the 'this'-pointer (and additionally of all local variables). Any
capture-access such as
state = m.non_const();
is transformed into
this_->state = this_->m.non_const();
where this_ is the copy of 'this'. This kind of indirection means that
it can be called in the const member function of the lambda closure w/o
breaking const.
Now you described that gcc 4.7.2 did not accept the call to the mutable
member function referred to by 'this'. If that is true, this must be a
defect in gcc 4.7.2 because for the same reasons as denoted above this
won't matter because we have only a copy of the 'this' pointer, not one
of the member.
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]