Ошибки при использовании лямбда-функции std :: for_each

У меня есть небольшая проблема, и я не могу понять, почему этот код не работает:

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

Ошибки, которые я получаю при компиляции:

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)'

я использую gcc 4.7.3так что, вероятно, поддержка C ++ 11 доступна для моего компилятора.

userBox_ это коллекция и BOOST_FOREACH правильно работает для этого кода:

BOOST_FOREACH(Wt::WString i, users)
{
std::cout << "ilosc: " << users.size() << std::endl;
userBox_->addItem(i);
}

Спасибо за любой ответ, мне так любопытно, почему это так.

4

Решение

Лямбда, которую вы написали, не фиксирует никаких переменных контекста. Для этого проще всего добавить & в список захвата лямбды. Это захватит все переменные контекста по ссылке, и вы сможете получить к ним доступ в лямбда-выражении.

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

Я не понимаю, почему ты печатаешь users.size() внутри цикла, потому что похоже, что результат будет одинаковым на каждой итерации. Если вы переместите это за пределы цикла и хотите получить более точный контроль над тем, что захватывает лямбда, вы можете изменить список захвата, чтобы захватывать только this указатель. Это позволит вам получить доступ к переменной-члену userBox_,

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

MSDN имеет отличную статью, объясняющую Синтаксис лямбда-выражения в мельчайших подробностях.

Наконец, в вашем случае нет необходимости std::for_each и лямбда. Было бы гораздо лаконичнее использовать диапазон на основе for цикл для добавления элементов в коллекцию.

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

Другие решения

Все, что вам нужно было знать, — это ошибки, которые вы получили.

Вы явно указали лямбда-выражению не перехватывать что-либо, используя «[]», что означает, что единственными переменными, к которым у него есть доступ внутри тела функции, являются параметры и глобальные переменные.

Неважно, какой тип userBox_, это переменная-член, поэтому лямбда должна захватывать «this».

Наконец, вы передаете по значению, что означает, что вы собираетесь дублировать каждый Wt :: WString. Вы можете вместо этого использовать

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

«&»захватывает по ссылке и захватит» это «для вас.

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

1

Захват переменных пользователей означает объявление вашей лямбды как:

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

который пройдет users как переменная только для чтения.

Чтобы быть в состоянии изменить users, вам нужно объявить вашу лямбду как:

    [&users](Wt::WString u){...}
0
По вопросам рекламы [email protected]