Феникс лямбда и разыменование аргументов - PullRequest
2 голосов
/ 22 сентября 2011

Может кто-нибудь показать мне, как реализовать эквивалент следующего, используя boost :: phoenix lambda?Я знаю, что мог бы реализовать это многими другими способами, но я пытаюсь выучить лямбда-выражения Феникса, и пока все мои попытки в этом примере потерпели неудачу.

Что я хочу сделать, это использовать std ::remove_if, чтобы выполнить итерацию по моему набору уязвимостей и удалить устаревшиене работайте с вызовом функции-члена для объекта с лямбда-аргументом, особенно когда существует более одного уровня косвенности.Т.е. ожидается, что _1 будет представлять собой итератор набора, который путем разыменования с помощью «->» возвращает значение value_type (будучи слабым_птром), для которого я хочу вызвать expired.Но поскольку _1 на самом деле не по прямому назначению итератор, а скорее "phoenix :: actor", моя разыменование не компилируется.

Заранее благодарен за все творческие материалы.*

Гейб

Ответы [ 2 ]

5 голосов
/ 22 сентября 2011

Boost.Phoenix и Boost.Lambda до него преуспевают в определенных задачах, но не в других. Один из тех, с которыми он не работает, связан с непосредственным вызовом функции по имени.

Boost.Phoenix лямбды могут быть быстро и легко созданы для перегруженных операторов. Но если вам нужно имя функции, то вы должны использовать уродливый синтаксис:

boost::phoenix::bind(&boost::weak_ptr::expired, boost::phoenix::arg_names::_1)

Так выглядит ваша лямбда. Вы можете использовать некоторые директивы using, чтобы обрезать пространства имен, но в конечном итоге это будет выглядеть так. Это на самом деле ничем не отличается от использования boost::bind на данный момент:

boost::bind(&boost::weak_ptr::expired, _1)

Boost.Phoenix и Boost.Lambda перед ним лучше всего использовать для лямбда-выражений, в которых используются перегруженные операторы, или явно определенных объектов действий Phoenix. Если у вас есть просто старая функция или функция-член, вы должны связать ее, чтобы вызвать. Так что вы можете просто использовать boost::bind.

2 голосов
/ 22 сентября 2011

Boost Phoenix (и Boost Lambda) не поддерживают оператор ->. Вы можете использовать оператор «указатель на член» (-> *) в качестве разумной альтернативы.

Я считаю полезным определить указатель на член как отдельную переменную непосредственно перед строкой, которая использует лямбда-выражение:

bool (weak_ptr<Xyz>::*expired)()const = &weak_ptr<Xyz>::expired ;
XyzWptrSetType::iterator it =
    std::remove_if(xyzWptrSet.begin(), xyzWptrSet.end(), (&_1->*expired)() );

Как уже отмечали другие, стоит рассмотреть bind () для таких ситуаций, как ваша.

...