Передача лямбда с параметром - PullRequest
4 голосов
/ 22 апреля 2011

Я бы хотел передать лямбду в функцию.

Это

boost::function<void()> fncPtr(boost::bind<void>([](){/* something */}));

работает, но если у лямбды есть параметр, я не знаю, как это сделать правильно:

boost::function<void(bool)>
fncPtr(boost::bind<void,bool>([](bool){/* something */}, _1));

не работает.

Где я не прав? Как передать лямбду с аргументом (ами)?

Я хотел бы сделать это в функции-члене. Так что в «глобальной области видимости» (это имя?) Этот метод работает отлично.

Ответы [ 3 ]

3 голосов
/ 22 апреля 2011

Это прекрасно работает для меня с GCC4.5:

#include <boost/bind.hpp>
#include <boost/function.hpp>

int main() {
  boost::function<void(bool)>
    fncPtr(boost::bind<void>([](bool){/* something */}, _1));
}

Ему не нужны типы параметров.Эти типы параметров в любом случае могут быть шаблонными (для некоторых функторов), поэтому в общем случае они не могут зависеть от них.Требуется только тип возвращаемого значения.

Кстати, у меня даже работает, когда я прохожу <void, bool>, но только тогда, когда у лямбд нет захватов.Я думаю, что это может работать для меня, потому что GCC4.5 поддерживает преобразование лямбда-выражений в типы указателей на функции, когда в лямбда-выражениях нет условия захвата.<void, bool> заставит bind иметь кандидата, который принимает указатель на функцию, и сделает лямбда-преобразование в него.Ваш компилятор, очевидно, еще не поддерживает это специальное преобразование (но FDIS требует этого).

Итак, просто передайте <void>, и оно должно работать.

2 голосов
/ 22 апреля 2011

Я подвел итог некоторым методам здесь, на Ideone .Обратите внимание, что я использовал версии C ++ 0x, версии Boost тоже должны нормально работать.
Это действительно зависит от того, что ваша функция хочет использовать в качестве параметра.Если это просто шаблон или принимает (std::|boost::)function, тогда подойдет простая лямбда.Нет необходимости в сложном переплетении или упаковке в дополнительные (std::|boost::)function.

0 голосов
/ 22 апреля 2011

Возможно, у вас проблема с компилятором. У меня тоже ошибка в Visual Studio 2010. Вы можете помочь компилятору преобразовать лямбду в функцию, используя вспомогательную функцию:

template <typename T>
void closureToFunction(bool x){ T f; return f(x); }

int main()
{
    auto exp = [](bool x){/* something */};
    boost::function<void(bool)> fncPtr( 
      boost::bind( closureToFunction<decltype(exp)>, _1) );
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...