I have a little problem and I can't figure out why this code doesn't work:
std::for_each(users.begin(), users.end(), [](Wt::WString u)
{
std::cout << "ilosc: " << users.size() << std::endl;
userBox_->addItem(u);
});
Errors that I get while compiling:
GameWidget.cpp: In lambda function:
GameWidget.cpp:352:30: error: 'users' is not captured
GameWidget.cpp:353:4: error: 'this' was not captured for this lambda function
GameWidget.cpp: In member function 'virtual void GameWidget::updateUsers()':
GameWidget.cpp:354:3: warning: lambda expressions only available with -std=c++11 or -std=gnu++11 [enabled by default]
GameWidget.cpp:354:4: error: no matching function for call to 'for_each(std::set<Wt::WString>::iterator, std::set<Wt::WString>::iterator, GameWidget::updateUsers()::<lambda(Wt::WString)>)'
GameWidget.cpp:354:4: note: candidate is:
In file included from /usr/include/c++/4.7/algorithm:63:0,
from GameWidget.h:11,
from GameWidget.cpp:9:
/usr/include/c++/4.7/bits/stl_algo.h:4436:5: note: template<class _IIter, class _Funct> _Funct std::for_each(_IIter, _IIter, _Funct)
GameWidget.cpp:354:4: error: template argument for 'template<class _IIter, class _Funct> _Funct std::for_each(_IIter, _IIter, _Funct)' uses local type 'GameWidget::updateUsers()::<lambda(Wt::WString)>'
GameWidget.cpp:354:4: error: trying to instantiate 'template<class _IIter, class _Funct> _Funct std::for_each(_IIter, _IIter, _Funct)'
I am using gcc 4.7.3
, so probably C++11 support is available for my compiler.
userBox_
is a collection and BOOST_FOREACH
works properly for this code:
BOOST_FOREACH(Wt::WString i, users)
{
std::cout << "ilosc: " << users.size() << std::endl;
userBox_->addItem(i);
}
Thanks for any answer, I'm so curious why is that.
The lambda you've written does not capture any context variables. To do this, the easiest is to add &
to the lambda's capture list. This will capture all context variables by reference and you'll be able to access them within the lambda.
std::for_each(users.begin(), users.end(), [&](Wt::WString u)
{
std::cout << "ilosc: " << users.size() << std::endl;
userBox_->addItem(u);
});
I don't understand why you're printing users.size()
within the loop, because it looks like the output is going to be the same every iteration. If you move that outside the loop, and want more fine grained control over what the lambda captures, you can modify the capture list to only capture the this
pointer. This will let you access the member variable userBox_
.
std::cout << "ilosc: " << users.size() << std::endl;
std::for_each(users.begin(), users.end(), [this](Wt::WString u)
{
userBox_->addItem(u);
});
MSDN has an excellent article explaining the lambda expression syntax in great detail.
Finally, in your case, there's no need for std::for_each
and a lambda. It would be a lot more succinct to use a range based for
loop to add the items to the collection.
for( auto const& u: users ) {
userBox_->addItem(u);
}
Everything you needed to know is in the errors you received.
You told the lambda, explicitly, not to capture anything, by using "[]", which means the only variables it has access to inside the function body are parameters and globals.
It doesn't matter what type userBox_ is, it's a member variable, so the lambda needs to capture "this".
Lastly, you're passing by value, which means you're going to duplicate each and every Wt::WString. You might want instead to use
std::for_each(users.begin(), users.end(), [&](const Wt::WString& u) {
...
});
The "&" captures by reference and will capture "this" for you.
http://en.cppreference.com/w/cpp/language/lambda
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With