не могу конвертировать boost :: lambda :: placeholder1_type

Я пытаюсь поиграть с boost :: lambda, но наткнулся на ошибку, не могу понять, как ее решить.

У меня такое чувство, что это ошибка новичка, поэтому, пожалуйста, извините за мое невежество (и, я должен признать, моя лень не читать всю документацию Boost Lamda тоже).

Кажется, что в некоторых случаях использование boost :: bind (или, может быть, boost :: lambda :: bind?) Лучше подходит, чем boost :: lambda, но я не уверен, что его можно применить здесь. Я не хотел бы писать отдельную функцию для if cond(arg1) arg2.insert(arg1) ;как бы победить цель; я думаю, это будет не намного лучше, чем функтор.

Я использую Boost 1,35 с VC9 на работе. Ошибки на cond() а также insert() вызывающие сайты:
«C2664: не удалось преобразовать параметр 1 из ‘boost :: lambda :: placeholder1_type»

Я повторил проблему с этим фрагментом с помощью g ++ на моем Cygwin.

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

#include <boost/foreach.hpp>
#include <iostream>
#include <set>

void work(  boost::function<void(long)> doAction ) {
long results[] = { 2, 5, 4 };
BOOST_FOREACH( long r, results )
doAction( r );
}

bool cond( long r ) { return r % 2 == 0 ; }

int main() {
using namespace boost::lambda;
std::set<long> myResults;
work(
if_then( cond(_1) , boost::ref(myResults).get().insert(_1) ) );

BOOST_FOREACH( long r, myResults )
std::cout << r << "\n";
}

ошибки g ++:

lambda_test.cpp: In function ‘int main()’:
lambda_test.cpp:21:19: error: cannot convert ‘boost::lambda::placeholder1_type {aka const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >}’ to ‘long int’ for argument ‘1’ to ‘bool cond(long int)’
if_then( cond(_1) , boost::ref(myResults).get().insert(_1) ) );
^
lambda_test.cpp:21:60: error: no matching function for call to ‘std::set<long int>::insert(boost::lambda::placeholder1_type&)’
if_then( cond(_1) , boost::ref(myResults).get().insert(_1) ) );

Любая помощь будет оценена,

Спасибо

3

Решение

Вы смешиваете отложенное выполнение с немедленной оценкой:

boost::ref(myResults).get().insert(_1)

Вот, boost::ref(myResults) не лень, так .get() тоже нет Тип boost::ref(myResults).get() является просто std::set<long> &и того типа insert Функция-член не имеет перегрузки, которая принимает заполнитель Boost Lambda.

Я не очень разбираюсь в Boost Lambda (больше), потому что я перешел в его библиотеку-преемника, Boost Phoenix. Вот перевод 1-к-1 с исправлениями: Жить на Колиру

#include <boost/phoenix.hpp>

#include <boost/foreach.hpp>
#include <iostream>
#include <set>

template <typename Action>
void work(  Action doAction ) {
long results[] = { 2, 5, 4 };
BOOST_FOREACH( long r, results )
doAction( r );
}

bool cond( long r ) { return r % 2 == 0 ; }int main() {
namespace phx = boost::phoenix;
using namespace phx::placeholders;

std::set<long> myResults;
work(
if_(phx::bind(cond, _1)) [ phx::insert(phx::ref(myResults), _1) ] );

BOOST_FOREACH( long r, myResults )
std::cout << r << "\n";
}

Печать

2
4

Я бы посоветовал взглянуть на адаптацию функций Phoenix, чтобы избежать выражений bind:

1

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