Errors using the lambda function std :: for_each

I have a little problem and I can not understand why this code does not work:

std::for_each(users.begin(), users.end(), [](Wt::WString u) { std::cout << "ilosc: " << users.size() << std::endl; userBox_->addItem(u); }); 

Errors I get when 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 maybe C ++ 11 support is available for my compiler.

userBox_ is a collection, and BOOST_FOREACH working correctly 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 this is.

+4
source share
3 answers

The lambda you wrote does not display any context variables. The easiest way to do this is to add & to the lambda capture list. This will allow you to capture all context variables by reference, and you can access them within 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 print users.size() in a loop because it looks like the output will be the same at each iteration. If you move this out of the loop and want more control over what lambda captures, you can change the capture list to capture only the this pointer. This will allow you to 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 perfectly describes the article lambda syntax expressions .

Finally, in your case there is no need for std::for_each and lambda. It would be much easier to use a range-based for loop to add items to the collection.

 for( auto const& u: users ) { userBox_->addItem(u); } 
+7
source

All you need to know is the errors you received.

You told yamba to not explicitly write anything using "[]", which means that the only variables that it has access to inside the function body are parameters and global variables.

It does not matter what type of userBox_ is, it is a member variable, so the lambda should capture "this".

Finally, you pass in a value, which means that you are going to duplicate every Wt :: WString. You can use instead

 std::for_each(users.begin(), users.end(), [&](const Wt::WString& u) { ... }); 

"&" captures by reference and will capture "this" for you.

http://en.cppreference.com/w/cpp/language/lambda

+1
source

Capturing the users variable means declaring your lambda as:

  [users](Wt::WString u){...} 

which users will pass as a read-only variable.

In order to be able to modify users , you need to declare your lambda as follows:

  [&users](Wt::WString u){...} 
0
source

Source: https://habr.com/ru/post/1482861/


All Articles